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
