例如,我有一个函数签名,如下所示:
declare function foo<T>(input: T): T;
,我希望它返回输入对象的严格类型,而无需手动设置模板类型:
const bar = foo({ str: 'foo', bool: true })
bar
的预期类型为:{ str: 'foo', bool: true }
而不是{ str: string; bool: boolean }
。
答案 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分配给一个类型参数,并且该类型参数被限制为可以作为文字类型的基本类型的类型,则该文字将保留文字类型。