[英]Generic mapped type constraint with optional member doesnt constraint when one of the member exist
const abc = <T extends object, P extends { [key in keyof T]?: number }>(
a: T,
b: P
) => {
console.log(a, b);
};
const A = { x: "1", y: "2", z: "3" };
const b = { x: 1, y: 2, z: 3 };
const b1 = { x: 1, y: 2 };
const b3 = { m: 5 };
const b4 = { m: 5, x: 1 };
abc(A, b);
abc(A, b1);
abc(A, b3); // Type '{ m: number; }' has no properties in common with type '{ x?: number | undefined; y?: number | undefined; z?: number | undefined; }'
abc(A, b4); // expect type error just like b3 but it is not
由於m
上不存在A
, b4
應該像b3
一樣出錯,對嗎? 但為什么它不是錯誤以及如何解決它?
這是沙盒代碼和框
鍵入'{ m:數字; }' 與類型 '{ x?: number | 沒有共同的屬性。 不明確的; y?: 數字 | 不明確的; z?: 數字 | 不明確的; }。
認為它很清楚,b4 沒有錯誤,因為有 x?, y? 之一 z? 包括。 那是因為您從 T 擴展,而 T 來自您傳遞的第一個參數是 A。
原來這根本不是關於 generics 的,這應該是代表我的問題的更好方法:
const abc = <T extends { [index: string]: string }>(
a: T,
b: { [key in keyof T]?: number }
) => {
console.log(a, b);
};
const A = { x: "1", y: "2", z: "3" };
const b4 = { m: 5, x: 1 };
abc(A, b4); // no error, not "expected"
abc(A, { m: 5, x: 1 }); // exact same value as b4 but throw error as "expected"
解決方案是您需要傳遞一個新值(不是變量的值)
有關解釋和其他解決方案(幫助類型),請閱讀此答案及其評論
更新,我找到了完美的解決方案:
const abc = <
T extends { [index: string]: string },
U extends { [key in keyof T]?: number }
>(
a: T,
b: keyof U extends keyof T ? U : never
) => {
console.log(a, b);
};
const A = { x: "1", y: "2", z: "3" };
const b4 = { x: 1, y: 2, z: 3 };
const b5 = { m: 2, x: 5 };
const b6 = { x: 1, y: 2, z: 3, m: 2 };
const b7 = { x: 1 };
abc(A, b4); // no error, excat member
abc(A, b5); // error, excess member
abc(A, b6); // error, excess member
abc(A, b7); // no error, one of the member exist
abc(A, {}); // no error, since it is optional
// all work as expected
這部作品無論價值是否新鮮
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.