List 从字符串列表a派生类型a
假设我有一个恒定不变的字符串列表List 从字符串列表a派生类型a,list,typescript,converter,List,Typescript,Converter,假设我有一个恒定不变的字符串列表a const a = ['b', 'c', 'd'] 我想创建一个a型,如下所示: type A = 'b' | 'c' | 'd' 我的问题是:如何从列表A自动创建类型A 另一种方法也适用于我:如果给定类型a,则如何创建列表a,因为数组是在运行时创建的,并且编译器无法确定对数组的更改。因此,它不能强制执行类型系统 例如,考虑以下内容: const array = [ "Bob", "James", "Dan" ]; let value: *A key of
a
const a = ['b', 'c', 'd']
我想创建一个a型,如下所示:
type A = 'b' | 'c' | 'd'
我的问题是:如何从列表A
自动创建类型A
另一种方法也适用于我:如果给定类型
a
,则如何创建列表a
,因为数组是在运行时创建的,并且编译器无法确定对数组的更改。因此,它不能强制执行类型系统
例如,考虑以下内容:
const array = [ "Bob", "James", "Dan" ];
let value: *A key of array*
setTimeout(() => {
value = "James";
}, 1000);
array.splice(1, 1);
在上述情况下会发生什么?调用value=“James
时,“James”
已从数组中删除,因此应引发错误!但这发生在运行时,因此编译器无法向您发出警告
解决方法是使用以下构造声明类型,但不能对其进行修改:
type MyType = "Bob" | "James" | "Dan"
let value: MyType = "Dan";
value = "Steven" // <- Compiler error!
键入MyType=“Bob”|“James”|“Dan”
let值:MyType=“Dan”;
value=“Steven”//是的,你可以这样做。唯一的障碍是如果你写
const a = ['b','c','d'];
// inferred as string[]
然后a
将被推断为string[]
,因此当您尝试派生a
时,文本值'a'
、'b'
和'c'
将被忘记。您可以始终明确地注释a
的类型:
const a: ['b','c','d'] = ['b','c','d'];
type A = typeof a[number];
//type A = "b" | "c" | "d"
但现在你在重复你自己,这是你试图避免的。有一个解决方案:
在中,我推荐了一个helper函数(tuple()
In)来推断元组类型
const a = tuple('b','c','d');
//inferred as type ["b", "c", "d"]
type A = typeof a[number];
//type A = "b" | "c" | "d"
如果您不关心它是一个元组,那么可以编写一个简单的数组推断辅助函数:
function inferLiteralArray<T extends string>(...arr: T[]): T[] {
return arr;
}
const a = inferLiteralArray("b", "c", "d");
//inferred as type ("b" | "c" | "d")[]
type A = typeof a[number];
//type A = "b" | "c" | "d"
零件的类型使用获取a的类型,该类型(对于tuple()
示例)为[“b”、“c”、“d”]
然后我使用了。如果您有一个类型T
和一个类型K
(因此它应该扩展keyof T
;您可以使用字符串文字,如“length”
,或数字文字,如0
,或这些字符的并集),那么T[K]
是在该键处可访问的属性类型。对于类数组类型A
,类型A[number]
获取该数组类型的元素类型。在元组示例中,这是一个并集,因为有多个number
类型的键具有不同的属性类型。(使用索引访问运算符时,T[K1 | K2]
应等于T[K1]| T[K2]
)。注意:
type TheTuple = typeof a; // ['b','c','d'];
type Zeroth = TheTuple[0]; // 'b'
type First = TheTuple[1]; // 'c'
type Second = TheTuple[2]; // 'd'
type A = TheTuple[number]; // 'b'|'c'|'d'
这有意义吗?除非运行时对象是不能修改的常量,如const a='a'
。我假设a
设置为常量且不可变。如何从列表a
创建类型?a
不是不可变的。可以执行a.push(“x”)在运行时修改ARAY.AWESCOME,它工作得很整洁!!!A[No]语法看起来像是对我来说是一个黑魔法。你能详细说明它为什么工作吗?见上面的更新1,欢迎你。如果你认为这个答案对你有帮助,请考虑投票和/或接受它。
type TheTuple = typeof a; // ['b','c','d'];
type Zeroth = TheTuple[0]; // 'b'
type First = TheTuple[1]; // 'c'
type Second = TheTuple[2]; // 'd'
type A = TheTuple[number]; // 'b'|'c'|'d'