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

typescript - ตัวสร้างคลาส พารามิเตอร์ตัวเลือก


ฉันต้องการที่จะสามารถเริ่มต้นคลาสด้วยหรือไม่ก็ได้ หากคุณส่งค่ามา เมธอดทั้งหมดของคลาสนี้จะคาดหวังค่าดังกล่าวเป็นอาร์กิวเมนต์ และค่าดังกล่าวจะเป็นชนิดเดียวกับที่คุณส่งมาตอนเริ่มต้น

ถ้าคุณไม่ส่งค่าอะไรไป เมทธอดจะไม่คาดหวังอาร์กิวเมนต์ใด ๆ และค่าจะเป็น undefined

ฉันคิดว่าบางโค้ดจะทำให้เป็นตัวอย่างที่ดีกว่า:

class Foo<T = void> {
  constructor(public type?: T) {}

  bar = (type: T) => {
    if (type) {
      this.type = type;
    }
  };
}

const fooUndefined = new Foo();

fooUndefined.bar(); // no errors, this is ok
fooUndefined.type === undefined; // no errors, this is ok
fooUndefined.bar(1); // expected error, this is ok

const fooNumber = new Foo(0);

fooNumber.type === 1; // no errors, but type is `number | undefined`, this is not ok
fooNumber.type > 0; // unexpected error because type is `number | undefined`, this is not ok

fooNumber.bar(1); // no errors, this is ok
fooNumber.bar(); // expected error, need to pass number, this is ok
fooNumber.bar('1'); // expected error, strings are not acceptable, this is ok

const fooUnion = new Foo<'a' | 'b'>() // no error, unexpected because it should not allow it
fooUnion.type.charAt(0) // unexpected error 

const fooUnion2 = new Foo<'a' | 'b'>('c') // expected error, this is ok
fooUnion2.type.charAt(0) // unexpected error 

ดังนั้นคุณสมบัติ type ในตัวอย่าง fooNumber เป็นประเภท number | undefined มีวิธีใดที่จะจำกัดเป็น number ได้โดยไม่ต้องใช้การแปลงประเภทอย่างชัดเจนหรือไม่?

ลิงก์สนามเด็กเล่น

คำตอบ #1

คุณไม่สามารถสร้างแบบจำลองสิ่งนั้นในลักษณะนี้ใน Typescript ได้จริง เพราะสิ่งที่คุณต้องทำคือการโอเวอร์โหลดตัวสร้างของคลาส และคุณทำไม่ได้ คุณ สามารถแก้ปัญหานี้ได้ด้วยฟังก์ชันแฟกทอรีที่โอเวอร์โหลด:

class Foo<T> {
  public type: T;
  constructor(type: T) { // param is no longer optional
    this.type = type;
  }

  bar(type: T) {
    if (type) {
      this.type = type;
    }
  }
}

function makeFoo(): Foo<void>
function makeFoo <T>(type: T): Foo<T>
function makeFoo <T = void>(type?: T): Foo<T> | Foo<void> {
  if (typeof type === 'undefined') {
    return new Foo<void>(undefined); // explicitly pass undefined
  }

  return new Foo<T>(type);
}

const fooUndefined = makeFoo();

fooUndefined.bar(); // no errors
fooUndefined.type === undefined; // no errors
fooUndefined.bar(1); // expected error, this is ok

const fooNumber = new Foo(0);

fooNumber.type === 1; // no error now
fooNumber.type > 0; // no error now

fooNumber.bar(1); // no errors
fooNumber.bar(); // expected error, need to pass number, this is ok
fooNumber.bar('1'); // expected error, strings are not acceptable, this is ok

const fooUnion = new Foo<'a' | 'b'>() // error, no longer allows it
fooUnion.type.charAt(0) // no error now

const fooUnion2 = new Foo<'a' | 'b'>('c') // expected error, this is ok
fooUnion2.type.charAt(0) // no error now

แม้ว่าฉันจะไม่แน่ใจว่าการปรับปรุงโค้ดปัจจุบันของคุณให้ใช้สิ่งนั้นจะง่ายหรือยากแค่ไหน

สนามเด็กเล่น

คำตอบ #2

พารามิเตอร์เงื่อนไขทั้งหมดได้รับ SomeType | undefined.

คุณสามารถเขียนแบบนี้เพื่อหลีกเลี่ยงมันได้

การแปลงเป็นตัวเลข

fooNumber.type as number > 2

หรือบอก TypeScript ว่าคุณแน่ใจว่ามีค่าที่ใช้งานได้โดยใช้นิพจน์ !

fooNumber.type! > 2 

บทความที่เกี่ยวข้อง