typescript如何对函数泛型参数解析的?

最近在学习ts类型体操,看到一题很有意思: 「重学TS 2.0 」TS 练习题第七题 #25

type EmptyObject = {
    [P in PropertyKey]: never
}

// 测试用例
const shouldPass: EmptyObject = {}; // 可以正常赋值
const shouldFail: EmptyObject = { // 将出现编译错误
    prop: "TS"
}

type SomeType = {
    prop: string
}

type StrictType<T1 extends T2, T2> = {
    [P in keyof T1]: P extends keyof T2 ? T1[P] : never
}

// 更改以下函数的类型定义,让它的参数只允许严格SomeType类型的值
declare function takeSomeTypeOnly<T extends SomeType>(x: StrictType<T, SomeType>): T

// 测试用例:
const x = { prop: 'a' };
takeSomeTypeOnly(x) // 可以正常调用

const y = { prop: 'a', addditionalProp: 'x' };
takeSomeTypeOnly(y) // 将出现编译错误

我的疑惑是在这一行

declare function takeSomeTypeOnly<T extends SomeType>(x: StrictType<T, SomeType>): T

请问在不明确传递泛型参数 T 的情况下,typescript 是如何解析 StrictType<T, SomeType> 的?

阅读 1.6k
1 个回答

chatGPT 回答:

在这段代码中,泛型参数 T 的类型是在调用函数 takeSomeTypeOnly 的时候传递的。当调用该函数时,函数的参数类型是 StrictType<T, SomeType>,所以输入类型 T 必须满足扩展自 SomeType 的条件。

因此,当你调用 takeSomeTypeOnly 时,你必须提供一个类型 T,这个类型必须继承自 SomeType,并且这个类型及其所有属性必须符合 StrictType<T, SomeType> 的约束。

例如,假设你有以下代码:

type MyType = {
  prop: string;
  otherProp: number;
};

const myValue: MyType = {
  prop: "value",
  otherProp: 123
};

const result = takeSomeTypeOnly(myValue);

在这种情况下,类型参数 T 的类型是 MyType。因为 MyType 扩展自 SomeType,所以它是合法的。而且,由于 MyType 符合 StrictType<MyType, SomeType> 的约束,所以它也是合法的。因此,在这种情况下,类型参数 T 的类型是 MyType。

logo
Microsoft
子站问答
访问
宣传栏