ข้อผิดพลาด TypeScript TS2345: 'type' สามารถมอบหมายให้กับข้อจำกัดของประเภท T ได้ แต่ T อาจถูกสร้างขึ้นด้วยชนิดย่อยที่แตกต่างกันของข้อจำกัด Value
นี่คือตัวอย่างโค้ดง่ายๆ ดังที่คุณเห็น ฟังก์ชันทั่วไปรับพารามิเตอร์ 1 ตัว ซึ่งเป็นอ็อบเจกต์ที่มีคุณสมบัติ 2 อย่าง v ขึ้นอยู่กับ generic T และ cb เป็นฟังก์ชัน callback ซึ่งรับอาร์กิวเมนต์ 1 ตัวที่มีชนิดเดียวกับ T และในแต่ละบล็อก type guard cb จะถูกเรียกด้วย v ที่ถูกเปลี่ยน ดังนั้นทำไม TypeScript ถึงเกิดข้อผิดพลาดเหล่านี้? จะแก้ไขอย่างไร?
type Value = string | number | string[];
const fn = <T extends Value>(p: {v: T; cb: (v: T) => void}) => {
const {v, cb} = p;
if (typeof v === 'number') {
cb(v + 1); // TS2345: Argument of type 'number' is not assignable to parameter of type 'T'.<br/>'number' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'SelectValue'.
} else if (typeof v === 'string') {
cb(`Hi ${v}`); // TS2345: Argument of type '`Hi ${T & string}`' is not assignable to parameter of type 'T'.<br/>'`Hi ${T & string}`' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'SelectValue'.<br/>Type '`Hi ${string}`' is not assignable to type 'T'.<br/>'`Hi ${string}`' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'SelectValue'.
} else {
cb([...v, 1]); // TS2345: Argument of type 'any[]' is not assignable to parameter of type 'T'.<br/>'any[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'SelectValue'.
}
};
// fn call examples
fn({
v: 1,
cb: (n: number) => {
console.log(n);
},
});
fn({
v: 'John',
cb: (n: string) => {
console.log(n);
},
});
fn({
v: [],
cb: (n: number[]) => {
console.log(n);
},
});