Typescript:获取变量的精确类型
拥有像这样的物体
const translations = {
say_hello: 'hello {{name}}',
};
我想提取对象的确切类型,就像
type Translations = {
say_hello: 'hello {{name}}',
}
到目前为止,我在玩一些像这样的东西
type GetExactType<T> = {[K in keyof T]-?: T[K]};
但是它没有按预期工作,因为
GetExactType<typeof translations>;
解析为
{
say_hello: string,
}
有什么想法吗?
答案#1
你可以使用 as const,但是那会导致所有内容都是 readonly,这可能不是你想要的。
相反,你可以有一个函数帮你缩小范围:
type Narrow<T> =
| (T extends infer U ? U : never)
| Extract<T, number | string | boolean | bigint | symbol | null | undefined | []>
| ([T] extends [[]] ? [] : { [K in keyof T]: Narrow<T[K]> });
function narrow<T>(t: Narrow<T>): T {
return t as T;
}
然后当你使用它时,它会为你推断类型:
const translations = narrow({
say_hello: 'hello {{name}}',
});
type T = typeof translations;
// ^? { say_hello: 'hello {{name}}'; }
请注意,一旦你这样定义它,就不可能恢复原始类型:
const translations = {
say_hello: 'hello {{name}}',
};
所以在将值赋值之前,需要对其进行某种直接操作。
操场
答案#2
你必须告诉 TypeScript,say_hello 属性的类型是 'hello {{name}}',而不是 string。至少有几种方法可以做到这一点:
通过
as const,表示该对象不会改变:const translations = { say_hello: 'hello {{name}}', } as const; //^^^^^^^^ type Translations = typeof translations;明确地:
const translations = { say_hello: 'hello {{name}}' as 'hello {{name}}', // −−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^ }; type Translations = typeof translations;(但是……呃……)
或者
const translations: { say_hello: 'hello {{name}}' } = { say_hello: 'hello {{name}}', }; type Translations = typeof translations; // (But if you were going to do that, you'd just want to write the type // alias manually and then apply it to the `translations` constant, rather // than doing it this way around.)
我经常把 as const 用于翻译字符串之类的东西。
操场链接
