关于泛型"keyof typeof"



你好,我在泛型键入方面遇到了一些困难。

interface ReturnValue {
keyA: string,
keyB: string
}

interface FilterA {
keyA: boolean;
}
interface FilterB {
keyB: boolean;
}

const func = function<T>(args: T) : Pick<ReturnValue, keyof typeof args> {
const res :Pick<ReturnValue, keyof typeof T> = {};
Object.keys(args).map(key => {
res[key] = key
}) 
return res;
}
console.log(func({keyB: true}).keyB); // should work
console.log(func({keyA: true}).keyA); // should work
console.log(func({keyA: true}).keyB); // should not work
console.log(func({keyC: true}).keyC); // should not work

但我有一个错误:

Type 'keyof T' does not satisfy the constraint 'keyof ReturnValue'.
Type 'string | number | symbol' is not assignable to type 'keyof ReturnValue'.
Type 'string' is not assignable to type 'keyof ReturnValue'.
Type 'keyof T' is not assignable to type '"keyB"'.
Type 'string | number | symbol' is not assignable to type '"keyB"'.
Type 'string' is not assignable to type '"keyB"'.(2344)

有什么想法吗?

当我使用函数调用时,它运行良好,我只能访问我作为参数提供的内容,但TS仍然显示此错误。

上下文为GraphQl。我的输入是一个对象,其中每个键的值都是truefalse。从这个对象中,我将构建一个GQL字符串查询,获取到api,返回的结构相同,但值不是boolean,而是string

TS游乐场

It使用Array.prototype.reduce并在此处映射类型:


interface FilterA {
keyA: boolean;
}
interface FilterB {
keyB: boolean;
}
type Filters = FilterA | FilterB
type Reduce<Obj> = {
[Prop in keyof Obj]: Prop
}
const func = <Obj extends Filters>(args: Obj) =>
Object.keys(args).reduce((acc, key) => ({
...acc,
[key]: key
}), {} as Reduce<Obj>)
func({ keyB: true }).keyB; // ok
func({ keyA: true }).keyA; // ok
func({ keyA: true }).keyB; // error
func({ keyC: true }).keyC // error

游乐场

我使用了这种方法的不可变版本,并不是因为它更好。我只是更喜欢不可变的数据结构。

更新

来自评论的Reduce替代版本的代码示例:

type Reduce<Obj> = {
[Prop in keyof Obj]: Prop extends keyof ReturnValue ? ReturnValue[Prop] : never
}

interface ReturnValue {
keyA: string,
keyB: string
}

最新更新