当前位置: 首页 > 知识库问答 >
问题:

javascript - ts类型implements后类型为never?

夏志国
2023-10-20
type ParamsA = { test: string }type ParamsB = { test: number }interface Base {  create(params: unknown): void}class PageA implements Base {  create(p: ParamsA) {  }}class PageB implements Base {  create(p: ParamsB) {  }}let a = 1const e = a > 1 ? new PageA() : new PageB()e.create({ test: '1' })

image.png

这里的 create 方法参数的类型理想状态下应该是 ParamsA | ParamsB,这里为什么会是 ParamsA & ParamsB

在线查看代码

共有2个答案

阙沛
2023-10-20

因为 ts 不知道 e 究竟是 PageA 还是 PageB,所以传入的参数必需同时对两种情况都有效,只能取两个实现的并集

贝研
2023-10-20

这个问题涉及到 TypeScript 的类型推断和类型别名。

在 TypeScript 中,当你定义了两个不同的类型(在本例中是 ParamsAParamsB),并且试图用条件语句(如 let e = a > 1 ? new PageA() : new PageB())来创建这两个类型的实例时,TypeScript 并不会推断出这是一个 ParamsA | ParamsB 的类型。相反,它只会推断出这是一个 ParamsA & ParamsB 的类型。

这是因为在 TypeScript 中,当你使用条件语句来创建对象时,它不会将参数类型视为可变动的,而是将其视为固定的。也就是说,不论条件语句的条件是什么,TypeScript 都会认为你创建的对象具有相同的类型。

在你的例子中,不论 a 的值是多少,你始终在创建 PageAPageB 的实例。因此,当你尝试调用 create 方法时,TypeScript 认为你传入的参数必须是 ParamsAParamsB 的实例。

然而,在你的代码中,你传入的参数是 { test: '1' },这是一个 string 类型的值,而不是 number 类型的值。因此,当 TypeScript 尝试将这个值分配给 ParamsA & ParamsB 类型的变量时,它会产生一个错误,因为 string 类型的值不能同时是 ParamsAParamsB 的实例。

解决这个问题的一种方法是使用类型断言。你可以在调用 create 方法时明确地告诉 TypeScript 你传入的参数的类型。例如:

e.create({ test: '1' } as ParamsA)

这样,你就告诉 TypeScript 你传入的参数是一个 ParamsA 的实例,因此它就不会产生错误了。

 类似资料:
  • 我正在尝试键入我的组件的props并同时使用URL参数。我得到以下错误: 类型“Readonly”上不存在属性“match” 以下是我的一些代码: 正如你所看到的,我想做的就是: 1-访问: http://localhost:8080/someStrings/:someString 2-在我的组件的构造函数中获取:一些字符串的值并存储在状态中 3-在我的状态中使用someString的值,以便能够

  • 在vue3和pinia使用ts type+sId+zId 三个都会报 “property type does not exist on object” 新补充 v1,v2...是接口返回来的,自己重新定义了新key,v1写在IUserState了没有报错,其他都飘红

  • 定义一个类型 条件1:变量类型是一个字符串。 条件2:变量值不是 get "typescript": "~5.2.2"

  • 关于ts as number 依旧是string 的问题 我这里代码已经在每一个步骤已经声明了是 number 但是依旧打印出来时是string 但是如果我使用 parseInt(sid) 又会提示我number 类型的参数不能赋值于 string 所以 类型转换是怎么转换的呢 ts 正确的类型转换

  • 一直认为implements只能实现interface,今天看到某个开源项目,prisma+nest,通过prisma的类型来定义entity,发现type也能实现,type不是仅仅是一个类型别名吗?