Ton*_*ony 10 type-inference typescript
我期待arg
param从父类中推断出类型
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 次 |
最近记录: |