如何在打字稿中获取严格的值类型?

时间:2019-03-21 05:40:14

标签: typescript

例如,我有一个函数签名,如下所示:

declare function foo<T>(input: T): T;

,我希望它返回输入对象的严格类型,而无需手动设置模板类型:

const bar = foo({ str: 'foo', bool: true })

bar的预期类型为:{ str: 'foo', bool: true }

而不是{ str: string; bool: boolean }

2 个答案:

答案 0 :(得分:4)

从TypeScript 3.4开始,编写

const bar = foo({ str: 'foo', bool: true } as const)

答案 1 :(得分:3)

我是as const及其功能的忠实支持者,它的问题在于调用者而不是决定是否应使用文字类型的函数。这可能会导致代表foo的用户感到困惑,当类型不是文字类型时,人们可能会忘记添加as const,并且在其他位置会出现奇怪的错误。

如果我们不再使用通常在打字稿中推断文字类型的方式,我们可以得到foo强制从其参数推断文字类型:

declare function foo<
   T extends Record<string, V>, 
   V extends string | boolean | number | symbol | null | undefined | Record<string, V>
>(input: T ): T;

const bar = foo({ str: 'foo', bool: true, o: { bar: "bar", n: 1 } }); 

// const bar: {
//     str: "foo";
//     bool: true;
//     o: {
//         bar: "bar";
//         n: 1;
//     };
// }

以上解决方案适用于嵌套对象,并且在大多数情况下应能很好地工作,并且消除了调用者添加as const的需要。此解决方案可在3.4及更高版本中使用。它依赖于这样一个事实,即如果将Typescript分配给一个类型参数,并且该类型参数被限制为可以作为文字类型的基本类型的类型,则该文字将保留文字类型。