typescript - 修改后的模板字面量类型

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/

相关文章:

css - TailwindCSS : is it possible to remove a box

rust - 为什么在堆栈中分配的值不会导致双自由指针?

r - 根据字符串匹配过滤列表

javascript - 如果其中没有图像, block 就会消失

rust - 为什么不可变结构在移入向量时会变为可变结构?

r - 将一列拆分为两列 : dataframes within a list

r - 使用逗号分隔的长度不等的数字字符串对多列进行数学运算

flutter - 如何在 Flutter App 上设置自定义图片图标?使用应用图标

node.js - 连接 redis 时在 docker-compose 中出现错误 : conne

javascript - 现代 Javascript 中的闭包 VS 类