const lines = ['one', 'two', 'three'] as const;
const linesWithA = lines.map(line => `${line}-A` as const);
const linesWithB = lines.map(line => `${line.toUpperCase()}-B` as const);
将给出类型:
declare const lines: readonly ["one", "two", "three"];
declare const linesWithA: ("one-A" | "two-A" | "three-A")[];
declare const linesWithB: `${string}-B`[];
是否有可能以某种方式为 linesWithB 获取类型 ("ONE-B"| "TWO-B"| "THREE-B")[]
?由于 toUpperCase
调用,我得到了 `${string}-A`[]
。
TS Playground
最佳答案
问题是 toUpperCase
只返回一个 string
:
const test1 = 'no uppercase'.toUpperCase();
// const test1: string
我认为处理这个问题最安全的方法是创建一个新函数 toUpperCase
并使用断言来获取正确的类型:
const toUpperCase = <S extends string>(line: S) =>
line.toUpperCase() as Uppercase<S>
const test2 = toUpperCase('uppercase');
// const test2: "UPPERCASE"
如果您在 linesWithB
中使用此函数,它将具有所需的返回类型:
const linesWithB = lines.map(line => `${toUpperCase(line)}-B` as const);
// const linesWithB: ("ONE-B" | "TWO-B" | "THREE-B")[]
Playground Link
更新:有一个 TypeScript issue关于这一点,但它(可能?)需要使 String
通用,这是一个相当广泛的变化。
https://stackoverflow.com/questions/71646698/