打字稿模板文字类型
Typescript Template Literal Type
有没有人 运行 Typescript 模板文字无法识别之前使用变量构造的类型?
这是代码片段:
const namespace = 'myNamespace';
type Keys = 'a' | 'b';
type NamespacedKeys = `${typeof namespace}/${Keys}`;
type NamespacedObjects = Record<NamespacedKeys, string>;
const foo: NamespacedObjects = {
[`${namespace}/a`]: 'bar',
[`${namespace}/b`]: 'toto',
} // this would have an error -> Type '{ [x: string]: string; }' is missing the following properties
const baz: NamespacedObjects = {
'myNamespace/a': 'bar',
'myNamespace/b': 'yolo',
} // this works
问题是编译器不会自动推断 template literal type when it encounters a template literal expression。例如:
const key = `${namespace}/a`;
// const key: string
key
的推断类型只是 string
而不是字符串文字。如果您希望编译器为此推断字符串文字类型,则需要使用 const
assertion:
明确要求它这样做
const key2 = `${namespace}/a` as const;
// const key2: "myNamespace/a"
想知道为什么这不会自动发生?嗯,在 microsoft/TypeScript#41891 to do this... and it apparently broke a bunch of real world code that was already using template literal expressions but depending on its type being just string
and not some string literal. So this was reverted in microsoft/TypeScript#42588 中完成了工作。现在我们只需要使用 const
断言,至少在 TS 团队弄清楚如何在不破坏太多现有代码的情况下获得更好的行为之前:
const foo: NamespacedObjects = {
[`${namespace}/a` as const]: 'bar',
[`${namespace}/b` as const]: 'toto',
} // okay
有没有人 运行 Typescript 模板文字无法识别之前使用变量构造的类型?
这是代码片段:
const namespace = 'myNamespace';
type Keys = 'a' | 'b';
type NamespacedKeys = `${typeof namespace}/${Keys}`;
type NamespacedObjects = Record<NamespacedKeys, string>;
const foo: NamespacedObjects = {
[`${namespace}/a`]: 'bar',
[`${namespace}/b`]: 'toto',
} // this would have an error -> Type '{ [x: string]: string; }' is missing the following properties
const baz: NamespacedObjects = {
'myNamespace/a': 'bar',
'myNamespace/b': 'yolo',
} // this works
问题是编译器不会自动推断 template literal type when it encounters a template literal expression。例如:
const key = `${namespace}/a`;
// const key: string
key
的推断类型只是 string
而不是字符串文字。如果您希望编译器为此推断字符串文字类型,则需要使用 const
assertion:
const key2 = `${namespace}/a` as const;
// const key2: "myNamespace/a"
想知道为什么这不会自动发生?嗯,在 microsoft/TypeScript#41891 to do this... and it apparently broke a bunch of real world code that was already using template literal expressions but depending on its type being just string
and not some string literal. So this was reverted in microsoft/TypeScript#42588 中完成了工作。现在我们只需要使用 const
断言,至少在 TS 团队弄清楚如何在不破坏太多现有代码的情况下获得更好的行为之前:
const foo: NamespacedObjects = {
[`${namespace}/a` as const]: 'bar',
[`${namespace}/b` as const]: 'toto',
} // okay