gpt4 book ai didi

typescript - 使用字符串文字数组作为类型

转载 作者:行者123 更新时间:2023-12-04 11:02:23 25 4
gpt4 key购买 nike

我想使用单个数组 const fruits = ['banana', 'apple', 'orange']作为普通数组,和作为 type .

我应该能够做到这一点:const x: fruits // => only accepts 'banana', 'apple' or 'orange'
并且还能够做到这一点:@IsIn(fruits)
我试图将数组声明为 <const> , 如:

const fruits = <const>['banana', 'apple', 'orange']
type Fruits = typeof fruits[number] // this evaluates to type: "banana" | "apple" | "orange"

但是 @IsIn(fruits)将返回以下错误:
Argument of type 'readonly ["banana", "apple", "orange"]' is not assignable to parameter of type 'any[]'.
The type 'readonly ["banana", "apple", "orange"]' is 'readonly' and cannot be assigned to the mutable type 'any[]'.ts(2345)

所以我想如果我创建了两个数组,一个普通数组和一个只读数组,它应该可以工作。所以我试过这个:

const fruits = ['banana', 'apple', 'orange']
const fruits_readonly: <const>[...fruits]
type Fruits = typeof fruits_readonly[number]

但现在 Fruits评估为 type: string而不是 type: "banana" | "apple" | "orange" .

最佳答案

const assertions确实如此使用 readonly 生成对象和数组元素。如果您想获得 const 的字符串字面量和元组类型的好处断言让你买单,同时也没有- readonly - 结果,您可以编写一个辅助函数来做到这一点。我会叫它mutable() :

const mutable = <T>(t: T): { -readonly [K in keyof T]: T[K] } => t

const fruits = mutable(['banana', 'apple', 'orange'] as const);
// const fruits: ["banana", "apple", "orange"]

这将工作一层深。如果您有嵌套的对象/数组类型,您可能需要创建 DeepMutable类型和 deepMutable()辅助功能:
type DeepMutable<T> =
T extends object ? { -readonly [K in keyof T]: DeepMutable<T[K]> } : T

const deepMutable = <T>(t: T) => t as DeepMutable<T>;

对于上述情况,这同样适用,
const alsoFruits = deepMutable(['banana', 'apple', 'orange'] as const);
// const alsoFruits: ["banana", "apple", "orange"]

但是对于嵌套对象,区别变得很重要:
const readonlyDeepFruits = {
yellow: ["banana", "lemon"],
red: ["cherry", "apple"],
orange: ["orange", "mango"],
green: ["lime", "watermelon"]
} as const;
/* const readonlyDeepFruits: {
readonly yellow: readonly ["banana", "lemon"];
readonly red: readonly ["cherry", "apple"];
readonly orange: readonly ["orange", "mango"];
readonly green: readonly ["lime", "watermelon"];
} */

const partiallyMutableDeepFruits = mutable(readonlyDeepFruits);
/* const partiallyMutableDeepFruits: {
yellow: readonly ["banana", "lemon"];
red: readonly ["cherry", "apple"];
orange: readonly ["orange", "mango"];
green: readonly ["lime", "watermelon"];
} */

const fullyMutableDeepFruits = deepMutable(readonlyDeepFruits);
/* const fullyMutableDeepFruits: {
yellow: ["banana", "lemon"];
red: ["cherry", "apple"];
orange: ["orange", "mango"];
green: ["lime", "watermelon"];
} */

好的,希望有帮助。祝你好运!

Link to code

关于typescript - 使用字符串文字数组作为类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58715915/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com