为什么不起作用?
class Demo<T, ArrayOfKeysOfT extends (keyof T)[]> {
constructor(args: {[index in keyof ArrayOfKeysOfT]: T[ArrayOfKeysOfT[index]]}) {
args;
}
}
我得到的错误提示
类型
ArrayOfKeysOfT[index]
不能用于索引类型T
。
但是看起来这段代码应该没问题。我不确定这是设计使然还是Typescript中的错误。
更新
我意识到这里的问题是ArrayOfKeysOfT[index]
,其中index
是类型keyof ArrayOfKeysOfT
不仅导致包含ArrayOfKeysOfT
的所有成员的类型,而且还包含一般情况下,数组的所有不同键(长度,推入,弹出等),这就是为什么不能将其用于键入T的原因。
我要完成的工作如下。
说我定义一些接口
interface Example {
one: string;
two: boolean;
}
那么应该允许
new Demo<Example, ['one', 'two']>({
one: "some string",
two: false
});
这应该导致编译器错误,因为类型参数数组中没有'two'
new Demo<Example, ['one']>({
one: "some string",
two: false
});
这应该导致编译器错误,因为三个不是第一个类型参数实参的键
new Demo<Example, ['one', 'two', 'three']>({
one: 'some string',
two: true,
three: 4
});
最后这应该不起作用,因为分配给args对象中成员'two'的值是错误的类型
new Demo<Example, ['one', 'two']>({
one: "some string",
two: "another string"
});
答案 0 :(得分:1)
class Demo<T, ArrayOfKeysOfT extends (keyof T)[]> {
constructor(args: {[P in ArrayOfKeysOfT[number]]: T[P]}) {
console.log(args);
}
}
interface ABC {
a: number;
b: string;
c: boolean;
}
const demo1 = new Demo<ABC, ['a', 'b']>({ 'a': 0, 'b': 'hi' }); // works!
const demo2 = new Demo<ABC, ['a', 'd']>({ 'a': 0, 'd': null }); // ERROR - Type '["a", "d"]' does not satisfy the constraint '("a" | "b" | "c")[]'
const demo3 = new Demo<ABC, ['c']>({ 'c': 'not a boolean' }); // ERROR - Type 'string' is not assignable to type 'boolean'.
const demo4 = new Demo<ABC, ['b', 'c']>({ 'a': 0 }); // ERROR - argument of type '{ 'a': number; }' is not assignable to parameter of type '{ b: string; c: boolean; }'.
我很乐意提供帮助!
更新:
只是想提醒您(或让您知道),内置的Pick<T, K>
工具类型存在于标准TypeScript库中,这使得Demo
类型的排序变得多余:
let a: Pick<ABC, 'a' | 'b'> = {'a': 2, 'b': 'hello'};