use*_*949 7 typescript typescript-generics
尽管验证有效,但我还是收到此错误。我所需要的只是一个函数,该函数使用对象来生成另一个函数来过滤固定类型的参数
Type 'keyof T' does not satisfy the constraint '"a" | "b" | "c"'.
Type 'string' is not assignable to type '"a" | "b" | "c"'.
Type 'keyof T' is not assignable to type '"c"'.
Type 'string' is not assignable to type '"c"'
Run Code Online (Sandbox Code Playgroud)
type GM = {
a: number;
b: string;
c: string
}
type VMeth<T, C > = (old: T, n: C) => any;
const getVF = <T extends { [key in keyof Partial<GM>]: 1 }>(part: T): VMeth<GM, Pick<GM, keyof T>> => {
return function(){ } as any
}
const fd = getVF({ a: 1 });
fd({ a: 1, b: "", c: "s"}, { a: 1 });
Run Code Online (Sandbox Code Playgroud)
约束条件
T extends { [key in keyof Partial<GM>]: 1 }
Run Code Online (Sandbox Code Playgroud)
意味着T必须可分配给{a?:1, b?:1, c?:1}. 这包括您尝试支持的类型,例如{a: 1}. 但它也包括您显然不想支持的类型。TypeScript 中的对象类型是可扩展的或开放的(而不是精确的或封闭的)。您可以通过向对象添加属性来扩展对象类型。{a?: 1, b?:1, c?:1, oops: string}所以也支持该类型:
const oopsie = getVF({ a: 1, oops: "oops" }) // no error!
// const oopsie: VMeth<GM, Pick<GM, "a" | "oops">>
Run Code Online (Sandbox Code Playgroud)
因为T实际上可能比 拥有更多的键GM,所以编译器正确地抱怨
// Type 'keyof T' does not satisfy the constraint 'keyof GM'.
Run Code Online (Sandbox Code Playgroud)
如果您确实想将 的键限制part为 的键GM(或者至少只注意这些键,因为无论您做什么,对象类型都是开放的),您可以使您的函数在这些键中通用K:
const getVF = <K extends keyof GM>(part: Record<K, 1>):
VMeth<GM, Pick<GM, K>> => {
return function () { } as any
}
Run Code Online (Sandbox Code Playgroud)
现在K必须是 的并集的某个子集"a" | "b" | "c",不能是"oops"或其他任何东西。所以Pick<GM, K>永远有效。您想要的用例仍然具有相同的功能:
fd({ a: 1, b: "", c: "s" }, { a: 1 });
// const fd: (old: GM, n: Pick<GM, "a">) => any
Run Code Online (Sandbox Code Playgroud)
现在,如果我们明显添加意外的属性,我们会收到编译器警告:
getVF({ a: 1, oops: "oops" }); // error, excess property!
Run Code Online (Sandbox Code Playgroud)
如果你偷偷摸摸,你仍然可以设法在那里获得如此多的财产:
const existingObj = {a: 1, oops: "oops"} as const;
const aliased: {a: 1} = existingObj;
const okay = getVF(aliased); // no error
// const okay: VMeth<GM, Pick<GM, "a">>
Run Code Online (Sandbox Code Playgroud)
但至少出来的值仍然是Pick<GM, "a">,而不是像 那样的无效值Pick<GM, "a" | "oops">。
| 归档时间: |
|
| 查看次数: |
26643 次 |
| 最近记录: |