打字稿模板文字类型

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

Playground link to code