[英]Typescript: DRY definition of string union and full array with the same item type
As shown elsewhere (eg TypeScript String Union to String Array ) it is easy to define union type from tuple:如别处所示(例如TypeScript String Union to String Array )很容易从元组定义联合类型:
const arr = ["foo", "bar"] as const
const Item = typeof arr[number]
Unfortunately I cannot use arr
where Item[]
is required - the type of arr
is readonly ["foo", "bar"]
, and even direct type cast results in typescript error TS2352.不幸的是,我不能在需要
Item[]
地方使用arr
- arr
的类型是readonly ["foo", "bar"]
,甚至直接类型转换也会导致打字稿错误 TS2352。
Typescripts suggests to cast to unknown
first - it works but it looks confusing and kind of defeats the whole purpose of type-safe array constant: Typescripts 建议先转换为
unknown
- 它有效,但它看起来令人困惑并且有点违背了类型安全数组常量的全部目的:
const _arr: Item[] = (arr as unknown) as Item[]
Is there any better way to have both the full list of options as Item[]
and Item
union type without repeating the actual options, other than above double cast?除了上面的双重转换之外,有没有更好的方法可以将完整的选项列表作为
Item[]
和Item
union type 而不重复实际选项?
What you want to do is type-unsafe .您想要做的是type-unsafe 。 Given
给定的
const arr = ["foo", "bar"] as const
If you could type the same arr
as Item[]
when using it somewhere, and then (for example) pass it to a function which accepts Item[]
as a parameter, that function could then do:如果您可以在某处使用它时键入与
Item[]
相同的arr
,然后(例如)将其传递给接受Item[]
作为参数的函数,则该函数可以执行以下操作:
arrayParameter.push('foo');
which would be perfectly fine because the parameter would still remain an Item[]
.这完全没问题,因为参数仍然是
Item[]
。 But the original type is now incorrect, because the mutated arr
is no longer ["foo", "bar"] as const
- rather, it has 3 items.但是原始类型现在不正确,因为变异的
arr
不再是["foo", "bar"] as const
- 相反,它有 3 个项目。
Slice (or otherwise somehow shallow copy) the array first if you want to use it as a generic Item[]
.如果您想将数组用作通用
Item[]
请先切片(或以其他方式以某种方式浅拷贝)数组。 There's no other way to do this which would be type-safe.没有其他方法可以做到这一点,这是类型安全的。
const arr = ['foo', 'bar'] as const;
type Item = typeof arr[number];
const arrItems: Item[] = arr.slice();
if your function takes readonly string[]
this as input, then you can pass existing arr, I know you might not have a control or change the function signature, but just throwing this out in case it helps如果您的函数将
readonly string[]
this 作为输入,那么您可以传递现有的 arr,我知道您可能没有控制权或更改函数签名,但只是将其扔掉以防万一
const tuple = ['foo', 'bar'] as const
function println(arr: readonly string[]) {
console.log(arr)
}
println(tuple)
println(['a', 'b', 'c'])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.