我期望 arg
参数具有从父类推断出的类型
export abstract class IEngineClas {
abstract viewer(arg: string): boolean
}
export class MyClass extends IEngineClas {
viewer(arg) {
return true
}
}
但是在实践中,编译器会提示 arg
的隐式类型为 any。
我也尝试过使用接口(interface)的方法
export interface IEngine {
viewer?: (arg: string) => boolean
}
export class MyClass implements IEngine {
viewer(arg) {
return true
}
}
它与编译器认为 arg
的类型相同。
为什么类型推断在这里不起作用?我该怎么做才能让它发挥作用?
最佳答案
当然可以推断!
Typescript 拥有有史以来最强大的通用系统!
它只需要一些神秘的语法。
你可以这样写(check it on Typescript Playground):
export abstract class IEngineClas {
abstract viewer(arg: string): boolean
}
export class MyClass extends IEngineClas {
viewer(arg: IEngineClas["viewer"] extends (arg: infer U) => any ? U : any) {
return true
}
}
let test = (new MyClass()).viewer("hop") // Type OK
let test2 = (new MyClass()).viewer(1) // Wrong type
说明:
IEngineClas["viewer"]
可以获取父函数的类型:(arg:string) => boolean
使用 conditional types ,您可以通过使用 infer 关键字将其分配给泛型来检索所需的 arg。
这样读:如果IEngineClas["viewer"]
的类型是(arg: U) => any
(带参数的函数),抓取U
(第一个参数)的类型,并将其用作参数 arg
的类型。否则,使用 any
类型。
编辑
更好的写法,使用类型 ( check it on Typescript Playground ):
type firstArg<T> = T extends (arg: infer U) => any ? U : any
export abstract class IEngineClas {
abstract viewer(arg: string): boolean
}
export class MyClass extends IEngineClas {
viewer(arg: firstArg<IEngineClas["viewer"]>) {
return true
}
}
let test = (new MyClass()).viewer("hop") // Type OK
let test2 = (new MyClass()).viewer(1) // Wrong type
原因
在另一个案例中,有一天我问为什么这些关于抽象类的预期推理行为不是默认的,并得到回答是由于性能问题。我承认在大型项目中,Typescript 变得非常慢。即使在抽象类上激活或不激活类型的编译标志也会受到欢迎。
我问的帖子:https://github.com/Microsoft/TypeScript/issues/21428
啊,还有...
如果您只想摆脱隐式任何警告,只需明确指定any
类型:viewer(arg:any)
,或在编译器选项中禁用 noImplicitAny 标志。
关于typescript - typescript 类中的类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49098473/