打字稿类中的类型推断 [英] Type inference in typescript classes

查看:29
本文介绍了打字稿类中的类型推断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望 arg 参数从父类推断类型

Im expecting the arg param to have inferred type from parent class

export abstract class IEngineClas {
  abstract viewer(arg: string): boolean
}

export class MyClass extends IEngineClas {
  viewer(arg) {
    return true
  }
}

然而在实践中,编译器抱怨 arg 的隐式类型为 any.

However in practice compiler complains that arg has implicit type of any.

我也尝试过使用界面的方法

I also tried approach with an interface

export interface IEngine {
  viewer?: (arg: string) => boolean
}

export class MyClass implements IEngine {
  viewer(arg) {
    return true
  }
}

它与编译器认为 arg 的类型为 any 有同样的问题.

It has the same issue with compiler thinking arg has type of any.

为什么类型推断在这里不起作用?我该怎么做才能让它发挥作用?

Why is type-inference not working here? And what can I do to get it to work?

推荐答案

当然可以推断!Typescript 拥有前所未有的强大通用系统!
它只需要一些神秘的语法.

Of course you can infer! Typescript has the most powerful generic system ever seen!
It just takes some mystic syntax.

你可以这样写(在 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) =>布尔值

Explanation:

IEngineClas["viewer"] can retrieve the type of your parent function: (arg:string) => boolean

使用条件类型,您可以通过使用 infer 关键字将其分配给泛型来检索您想要的参数.

Using the conditional types, you can retrieve the arg you want by using the infer keyword to assign it to a generic.

这样读:如果 IEngineClas["viewer"] 的类型是 (arg: U) =>any(带参数的函数),获取U的类型(第一个参数),作为参数arg的类型.否则,使用 any 类型.

Read it like this: if the type of IEngineClas["viewer"] is (arg: U) => any (a function with an argument), grab the type of U (the first argument) and use it as the type of the parameter arg. Otherwise, use the type any.

一种更好的编写方式,使用类型(在 Typescript Playground 上查看):

A better way to write it, with a type (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 变得非常缓慢.即使在抽象类上激活类型的编译标志也会受到欢迎.

The reason

On a different case, I asked one day why these expected inference behaviors concerning the abstract classes weren't the default, and was answered it was due to performance issues. And I admit that on big projects, Typescript becomes excessively slow. Even if a compilation flag to activate the typings or not on the abstract classes would have been welcomed.

我问的帖子:https://github.com/Microsoft/TypeScript/issues/21428

如果您只是想摆脱隐式 any 警告,只需明确指定 any 类型:viewer(arg:any),或在编译器选项中禁用 noImplicitAny 标志.

If you just want to get rid of the implicit any warning, just specify the any type explicitly: viewer(arg:any), or disable the noImplicitAny flag in your compiler options.

这篇关于打字稿类中的类型推断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆