繁体   English   中英

TypeScript:如何根据另一个泛型推断一个泛型的类型?

[英]TypeScript: How to infer the type of one generic based on another generic?

我有这个代码:

class A<T> {
    a(t: T) {
        console.log(t);
    }
}

class B<T, O extends {b: T}> {
    constructor(public a: A<O>) {
    }

    b(t: T) {
        console.log(t)
    }
}

const a = new A<{b: number}>(); // type: A<{ b: number; }>

const b = new B(a); // type: B<unknown, { b: number; }>

为什么 TypeScript 将 class B的方法b的参数标记为未知?

你认为它应该推导出T = number吗? 如果条件是O equals { b: T } (你不能写),那就是真的。 但是由于number extends {}我们也可以有T = {}

在此代码中, g将具有类型true

type G<T> = { b: number } extends { b: T } ? true : false;
let g: G<{}>;

我们有类型TO ,其中O extends {b: T} TO['b']之间的关系是O['b'] extends T 这意味着T可以完全是O['b']但它也可以是比O['b']更广泛的任何类型。

typescript 无法推断这种推理方向,因为T有无数种类型,因此number extends T 正如@md2perpe 所建议的那样,您可以拥有像any{}这样的非常广泛的类型。 你可以有一个包含number的联合,比如string | number string | number

为了能够推断出第二个参数,我们需要以另一种方式extends到 go。 我们需要知道T必须比O['b'] 我们可以这样写:

class B<T extends O['b'], O extends {b: any}> {

这里我们说O是一些具有b属性的 object。 我们说T是某种类型,它要么是Ob值,要么是它的子集。 现在 typescript 将推断TO['b']

const a = new A<{b: number}>(); // type: A< b: number; }>

const b = new B(a); // type: B<number, { b: number; }>

b.b(5) // takes type: number

请注意,您仍然可以手动将T设置为更窄的类型:

const specificB = new B<5, {b: number}>(a); // type: B<5, { b: number; }>

specificB.b(10); // error: Argument of type '10' is not assignable to parameter of type '5'.

Typescript 游乐场链接

我想我明白了这里的问题所在。 class B有两个泛型类型参数TO B的构造函数只接受A<O>类型的参数,但不接受T类型的参数。 所以当你创建一个新的B时,没有办法告诉T应该绑定到什么。 尝试new B<Type1, Type2>(a)来帮助编译器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM