为什么打字稿无法通过其字段推断通用类型?

lim*_*dev 5 typescript typescript-generics

我不明白为什么有时打字稿无法推断 const 的泛型类型。

这是一个例子:

type OneTwoThree = 1 | 2 | 3;

type MyType<num extends OneTwoThree> = {
    n: num;
}

const first: MyType = { // <-- Generic type 'MyType' requires 1 type argument(s).(2314)
    n: 2,
};

const second: MyType<3> = {
    n: 3,
};
Run Code Online (Sandbox Code Playgroud)

为什么打字稿不能推断出它的first类型MyType<2>

我也尝试过MyType以这种方式声明:

type MyType<num extends OneTwoThree = OneTwoThree> = {
    n: num;
}
Run Code Online (Sandbox Code Playgroud)

但这样首先就成为了类型const first: MyType<OneTwoThree>......

这是游乐场链接: https: //www.typescriptlang.org/play ?#code/C4TwDgpgBA8gdhAKgdwPaIBYCcLQLxQCMUAPlAEylQDMA3AFD2iRQCyIi4EAPHAK4BbKBAAewCHAAmAZ1gIU6bLigF4SNJhwQAfCqgBvelGNQ4ALLOCGAX0YBjVHGnAoAMwCWWZxfacWBQxNT C3IAGnprBnoHJxdpCBjJHw4ubmpdAKMTcxpwyKA

有什么建议么?

jca*_*alz 9

这是 TypeScript 所缺少的功能;编译器不会推断泛型 类型中的类型参数,就像N您的MyType<N>. 正如您所注意到的,使用通用参数默认值不会执行此操作;当您使用默认值时,您将获得默认值而不是类型推断。仅当您调用泛型函数时,编译器才会尝试推断类型参数。

microsoft/TypeScript#32794上有一个相当长的开放请求,要求支持泛型类型中的类型参数推断,但目前它还不是该语言的一部分。请注意,由于存在通用参数默认值,因此您将无法像const first: MyType = .... 您也许可以编写类似 的内容const first: MyType<infer> = ...,并且可能重写默认值,使其类似于type MyType<N extends OneTwoThree = infer> = ...,但这只是猜测,因为它还不是一个功能。

除非提供这样的功能,否则通常的解决方法是编写通用辅助身份函数。该函数除了返回其输入之外不执行任何操作,但是当您调用通用函数时,您会得到您正在寻找的推论。因此const first: MyType = {...},您可以写const first = asMytype({...})

const asMyType = <N extends OneTwoThree>(m: MyType<N>) => m;

const first = asMyType({
    n: 2,
});
// const first: MyType<2>
Run Code Online (Sandbox Code Playgroud)

Playground 代码链接