在我的 typescript 函数中,我想强制第二个参数的所有键必须属于第一个参数的对象。
类似的东西
mapTo([new KeyValue('a', 'b'), new KeyValue('x', 'y')], {key: {key2: 1}});
在此第二个参数的所有键(key 和key2)必须属于 KeyValue 对象的键
这里的键值是:
class KeyValue {
key: string;
key2: string;
constructor(k, k2) {
this.key = k;
this.key2 = k2;
}
}
喜欢
mapTo([new KeyValue('a', 'b')], {key: {key2: 1}}); -> ok
mapTo([new KeyValue('a', 'b')], {key: {key3: 1}}); -> error // invalid key3
为此我实现了 mapTo 函数
public nest<T, K extends keyof T, K2 extends keyof T>(arr: [T], basis: {[k in K]: {[k2 in K2]}}) {
console.log('Hello!!!');
console.log(basis);
}
此代码工作完美,但如果我在 KeyValue 类中添加另一个键并将此键传递到参数中,如下所示:
mapTo([new KeyValue('a', 'b' ,'c')], {key: {key2: {key3: 1}}});
和 KeyValue 到:
class KeyValue {
key: string;
key2: string;
key3: string;
constructor(k, k2, k3) {
this.key = k;
this.key2 = k2;
this.key2 = k3;
}
}
然后我上面实现的函数不会验证第三个 key
那么我怎样才能实现上述功能,使其接受动态嵌套值并完美地工作。
更多例子:
mapTo([new KeyValue('a', 'b' ,'c')], {key: 1}); -> okay
mapTo([new KeyValue('a', 'b' ,'c')], {key: {key1:1}}); -> okay
mapTo([new KeyValue('a', 'b' ,'c')], {key1: {key:1}}); -> okay
mapTo([new KeyValue('a', 'b' ,'c')], {key1: {key:{key3:1}}}); -> okay
mapTo([new KeyValue('a', 'b' ,'c')], {key1: {key:{key4:1}}}); -> error // key4 not exist
mapTo([new KeyValue('a', 'b' ,'c')], {key3: {key2:0}); -> okay
最佳答案
您可以使用递归映射类型来定义一个结构,该结构允许在每个级别指定 T
的任何键。我们还可以通过使用 Omit
类型省略每个级别上的当前键来确保在路径中没有指定两次键:
type Diff<T extends string, U extends string> = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T];
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>;
type Nested<T> = { [P in keyof T]?: Nested<Omit<T, P>> | number }
function mapTo<T>(arr: [T], basis: Nested<T>) {
console.log('Hello!!!');
console.log(basis);
}
class KeyValue {
constructor(public key: string, public key1: string, public key3: string) {
}
}
mapTo([new KeyValue('a', 'b', 'c')], { key: 1 }); //-> okay
mapTo([new KeyValue('a', 'b', 'c')], { key: { key1: 1 } }); //-> okay
mapTo([new KeyValue('a', 'b', 'c')], { key1: { key: 1 } }); //-> okay
mapTo([new KeyValue('a', 'b', 'c')], { key1: { key: { key3: 1 } } }); //-> okay
mapTo([new KeyValue('a', 'b', 'c')], { key1: { key: { key4: 1 } } }); //-> error // key4 not exist
mapTo([new KeyValue('a', 'b', 'c')], { key: { key: 1 } }); //-> error, key appears twice
关于javascript - 强制函数的参数必须属于泛型类型 T,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49350891/