问题描述
如其他地方所示(例如TypeScript String Union to String Array),可以很容易地从元组中定义联合类型:
const arr = ["foo","bar"] as const
const Item = typeof arr[number]
不幸的是,我无法在需要arr
的地方使用Item[]
-arr
的类型为readonly ["foo","bar"]
,甚至直接类型转换也会导致打字错误TS2352。
Typescripts建议首先转换为unkNown
-它可以工作,但看起来令人困惑,并且有损于类型安全数组常量的整个目的:
const _arr: Item[] = (arr as unkNown) as Item[]
除了双重强制转换之外,是否有更好的方法可以同时包含Item[]
和Item
联合类型的完整选项列表,而无需重复实际选项?
解决方法
您要执行的操作是类型不安全。给定
const arr = ["foo","bar"] as const
如果您在某处使用时可以输入与arr
相同的Item[]
,然后(例如)将其传递给接受Item[]
作为参数的函数,则该函数可以然后做:
arrayParameter.push('foo');
,因为参数仍将保持为Item[]
,这将是非常好的。但是原来的类型现在不正确,因为突变的arr
不再是["foo","bar"] as const
了-它具有3个项目。
如果要将其用作通用Item[]
,请先切片(或以其他方式进行浅表复制)数组。没有其他方法可以做到类型安全。
const arr = ['foo','bar'] as const;
type Item = typeof arr[number];
const arrItems: Item[] = arr.slice();
,
如果您的函数将readonly string[]
用作输入,那么您可以传递现有的arr,我知道您可能没有控件或更改了函数签名,但是只要有帮助就扔掉它
const tuple = ['foo','bar'] as const
function println(arr: readonly string[]) {
console.log(arr)
}
println(tuple)
println(['a','b','c'])