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' })
这里的 create
方法参数的类型理想状态下应该是 ParamsA | ParamsB
,这里为什么会是 ParamsA & ParamsB
在线查看代码
因为 ts
不知道 e
究竟是 PageA
还是 PageB
,所以传入的参数必需同时对两种情况都有效,只能取两个实现的并集
这个问题涉及到 TypeScript 的类型推断和类型别名。
在 TypeScript 中,当你定义了两个不同的类型(在本例中是 ParamsA
和 ParamsB
),并且试图用条件语句(如 let e = a > 1 ? new PageA() : new PageB()
)来创建这两个类型的实例时,TypeScript 并不会推断出这是一个 ParamsA | ParamsB
的类型。相反,它只会推断出这是一个 ParamsA & ParamsB
的类型。
这是因为在 TypeScript 中,当你使用条件语句来创建对象时,它不会将参数类型视为可变动的,而是将其视为固定的。也就是说,不论条件语句的条件是什么,TypeScript 都会认为你创建的对象具有相同的类型。
在你的例子中,不论 a
的值是多少,你始终在创建 PageA
或 PageB
的实例。因此,当你尝试调用 create
方法时,TypeScript 认为你传入的参数必须是 ParamsA
或 ParamsB
的实例。
然而,在你的代码中,你传入的参数是 { test: '1' }
,这是一个 string
类型的值,而不是 number
类型的值。因此,当 TypeScript 尝试将这个值分配给 ParamsA & ParamsB
类型的变量时,它会产生一个错误,因为 string
类型的值不能同时是 ParamsA
和 ParamsB
的实例。
解决这个问题的一种方法是使用类型断言。你可以在调用 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不是仅仅是一个类型别名吗?