ค้นหาเว็บไซต์

ข้อผิดพลาด 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 &amp; string}`' is not assignable to parameter of type 'T'.<br/>'`Hi ${T &amp; 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);
  },
});