typescript - typescript 类中的类型推断

标签 typescript type-inference

我期望 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/

相关文章:

javascript - 寻找最有效的方法将已知格式的字符串解析为 Typescript 中的对象数组

javascript - 使用 "UNABLE_TO_GET_ISSUER_CERT_LOCALLY"命令时获取 "tsd"

haskell - 从运算符推断类型类别

十进制的 C# 类型后缀

xcode - swift 如何推断 num1 和 num2 是整数?

angular - 在 Angular 5 中测试 @ContentChildren()

angular - 将 HTML 文件读入 Angular 2 中的模板?

javascript - Typescript 返回值或柯里化(Currying)函数

arrays - 为什么此列表推导式返回 Array{Any,1} 而不是 Array{Symbol,1}?

types - 为什么不能为嵌套函数推断类型