[英]TypeScript TupleIndexed type and enforce read only for arrays passed in as arguments
I want to create type
in TypeScript that takes a type parameter T
and tuple/ReadonlyArray of keyof T
and returns a ReadonlyArray of the keys indexed into T
.我想在 TypeScript 中创建
type
,它采用类型参数T
和keyof T
元组/ReadonlyArray 并返回索引到T
的键的 ReadonlyArray 。
type TupleIndexed<T, K extends ReadonlyArray<keyof T>> = {
[C in keyof K]: T[C];
};
But I get Type 'C' cannot be used to index type 'T'
.但是我得到
Type 'C' cannot be used to index type 'T'
。
One workaround I found is我发现的一种解决方法是
type TupleIndexed<T, K extends ReadonlyArray<keyof any>> = {
[C in keyof K]: K[C] extends keyof T ? T[K[C]] : never;
};
While it gets the job done, I don't understand why the conditional is necessary for the compiler.虽然它完成了工作,但我不明白为什么编译器需要条件。
This way I'm able to write typed functions that preserve the positional type information like the following这样我就可以编写保留位置类型信息的类型化函数,如下所示
function pluck<T, K extends ReadonlyArray<keyof T>>(obj: T, keys: K): TupleIndexed<T, K> {
return keys.map(key => obj[key]);
}
const vals = pluck({name: 'John', age: 25, adult: true}, [
'name',
'age',
'adult'
] as const);
const name = vals[0]; // string
const age = vals[1]; // number
const adult = vals[2]; // boolean
const doesNotExist = vals[3]; // ERROR
However, even in this solution, not casting the array as const
still compiles但是,即使在这个解决方案中,不将数组转换
as const
仍然可以编译
function pluck<T, K extends ReadonlyArray<keyof T>>(obj: T, keys: K): TupleIndexed<T, K> {
return keys.map(key => obj[key]);
}
const vals = pluck({name: 'John', age: 25, adult: true}, [
'name',
'age',
'adult'
]); // Not explicitly stating as const still compiles
const name = vals[0]; // string | number | boolean
const age = vals[1]; // string | number | boolean
const adult = vals[2]; // string | number | boolean
const doesNotExist = vals[3]; // string | number | boolean
Which loses all the positional type safety.这失去了所有的位置类型安全。 Is there a way to automatically cast the array
as const
or otherwise have the compiler throw an error when it isn't casted as const
?有没有办法自动将数组转换
as const
或者当它没有转换as const
时,编译器会抛出错误?
Is there a way to automatically cast the array as
const
or otherwise have the compiler throw an error when it isn't casted asconst
?有没有办法自动将数组转换为
const
或者当它没有转换为const
时,编译器会抛出错误?
As far as I know, there is not.据我所知,没有。
However, using a rest parameter instead of an array will result in TypeScript treating it as a tuple instead of an array.但是,使用 rest 参数而不是数组将导致 TypeScript 将其视为元组而不是数组。 Of course this also means have to call it slightly differently:
当然,这也意味着必须稍微不同地称呼它:
type TupleIndexed<T, K extends ReadonlyArray<keyof any>> = {
[C in keyof K]: K[C] extends keyof T ? T[K[C]] : never;
};
function pluck<T, K extends ReadonlyArray<keyof T>>(obj: T, ...keys: K): TupleIndexed<T, K> {
// ^^^
return keys.map(key => obj[key]) as any;
}
const vals = pluck({name: 'John', age: 25, adult: true}, 'name', 'age', 'adult');
const name = vals[0]; // string
const age = vals[1]; // number
const adult = vals[2]; // boolean
const doesNotExist = vals[3]; // error
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.