Ton*_*ony 10 type-inference typescript
我期待argparam从父类中推断出类型
export abstract class IEngineClas {
abstract viewer(arg: string): boolean
}
export class MyClass extends IEngineClas {
viewer(arg) {
return true
}
}
Run Code Online (Sandbox Code Playgroud)
但是在实践中编译器抱怨arg具有任何隐式类型.
我也试过接口
export interface IEngine {
viewer?: (arg: string) => boolean
}
export class MyClass implements IEngine {
viewer(arg) {
return true
}
}
Run Code Online (Sandbox Code Playgroud)
它有同样的问题,编译器思维arg具有任何类型.
为什么类型推断在这里不起作用?我能做些什么让它发挥作用?
这里没有类型推断.父类或实现的接口不会推断成员类型.arg不是推断, string而是隐含的 any.
只要与父方法兼容,子类就有可能覆盖方法签名.可以将方法定义为 viewer(arg: any) {...}.由于string是的一个子集any,,这将是允许的,而viewer(arg: boolean) {...}不会.
viewer(arg) {...}结果是隐含any的arg,它与...相同viewer(arg: any) {...}.它将在松散的编译器模式下工作,但会导致类型错误strict或noImplicitAny编译器选项.noImplicitAny 特别有助于避免any在像这样的情况下意外推断.
当然可以推断!
Typescript具有有史以来功能最强大的通用系统!
它只需要一些神秘的语法。
您可以这样写(在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
Run Code Online (Sandbox Code Playgroud)
IEngineClas["viewer"] 可以检索父函数的类型: (arg:string) => boolean
使用条件类型,您可以通过使用infer关键字将其分配给泛型来检索所需的arg 。
像这样阅读:如果类型IEngineClas["viewer"]为(arg: U) => any(带有参数的函数),请抓住U(第一个参数)的类型并将其用作参数的类型arg。否则,请使用type any。
一种更好的编写类型的方法(请在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
Run Code Online (Sandbox Code Playgroud)
在另一种情况下,我有一天问为什么与抽象类有关的这些预期推断行为不是默认行为,并回答这是由于性能问题引起的。我承认在大型项目中,Typescript变得非常慢。即使在抽象类上激活或不激活键入的编译标志也将受到欢迎。
我问过的帖子:https : //github.com/Microsoft/TypeScript/issues/21428
如果只想消除隐式的任何警告,只需any显式指定类型:viewer(arg:any),或在编译器选项中禁用noImplicitAny标志。
| 归档时间: |
|
| 查看次数: |
607 次 |
| 最近记录: |