如何将现有数组转换为 TypeScript 字符串字面类型?

huangapple go评论116阅读模式
英文:

How to convert existing array to TypeScript string literal type?

问题

https://stackoverflow.com/questions/44497388/typescript-array-to-string-literal-type 问及并收到了有关如何在数组声明时创建字符串字面类型的答案。我想知道是否可能从一个 已经存在的 数组创建一个字符串字面类型。

以相同的基本示例为例:

const furniture = ['chair', 'table', 'lamp'];
type Furniture = 'chair' | 'table' | 'lamp';

在声明时建议的已知解决方案是:

const furniture = ['chair', 'table', 'lamp'] as const;

这将将数组锁定为 readonly。是否可能只需取数组并从中创建一个新项目?

const furniture = ['chair', 'table', 'lamp'];
const furnitureLiteral = furniture as const;

// 生成:"readonly [string[]]" 类型。
// 希望得到:"readonly ["chair", "table", "lamp"]" 类型。

或者是否由于静态类型而不可能?

英文:

https://stackoverflow.com/questions/44497388/typescript-array-to-string-literal-type asks and receives an answer regarding how to create a string literal upon array declaration. I am wondering if it is possible to create a string literal from an already existing array.

To take the same basic example:

const furniture = ['chair', 'table', 'lamp'];
type Furniture = 'chair' | 'table' | 'lamp';

the suggested known solution at declaration is:

const furniture = ['chair', 'table', 'lamp'] as const;

This locks the array to a readonly. Is it possible to just take the array and make a new item from it?

const furniture = ['chair', 'table', 'lamp'];
const furntureLiteral = furniture as const;

// Yields: "readonly [string[]]" typing.
// Wanted: "readonly ["chair", "table", "lamp"]" typing.

Or is it impossible due to static typing?

答案1

得分: 1

你想要使用 furniture 来完成两个不同的目的:一是记住它初始化时的字符串文字类型,但也可以在将来保存任意其他字符串。 TypeScript 实际上无法使用单个变量同时满足这两个需求。最简单的解决方法可能是使用两个变量,一个用于每个目的。

你可以通过 const 断言 来跟踪初始化器,它会“锁定”结果变量:

const initialFurniture = ['chair', 'table', 'lamp'] as const;
type InitialFurniture = typeof initialFurniture[number];
// type InitialFurniture = "chair" | "table" | "lamp"

然后将其复制到一个可变的字符串数组中,这样你可以随心所欲地添加任何字符串:

const furniture: string[] = [...initialFurniture];
furniture.push("futon");
furniture.push("hammock");
furniture.push("cupboard");

现在你已经分离了这两个用途,TypeScript 编译器也会满意。

Playground 链接到代码

英文:

You want to use furniture for two different purposes: remembering the string literal types of the values it's initialized with, but also holding arbitrary other strings in the future. TypeScript doesn't really give you the flexibility to do both with a single variable. The easiest way forward could be to have two variables, one for each purpose.

You can keep track of the initalizer via a const assertion which "locks" the resulting variable:

const initialFurniture = ['chair', 'table', 'lamp'] as const;
type InitialFurniture = typeof initialFurniture[number];
// type InitialFurniture = "chair" | "table" | "lamp"

And then copy that into a mutable string array that lets you do anything you want:

const furniture: string[] = [...initialFurniture];
furniture.push("futon");
furniture.push("hammock");
furniture.push("cupboard");

Now you've separated the concerns and the TypeScript compiler is satisfied also.

Playground link to code

huangapple
  • 本文由 发表于 2023年3月15日 19:36:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75744168.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定