การใช้ type เป็นพารามิเตอร์ typescript
วิธีใช้ type เป็นพารามิเตอร์ใน typescript
type myType = {}
const passingType = (t: Type) => {
const x : t = {}
}
passingType(myType);
ฉันได้รับข้อผิดพลาด TS
't' refers to a value, but is being used as a type here. Did you mean 'typeof t'?
และ
'myType' only refers to a type, but is being used as a value here.ts(2693)
สำหรับการโทร
ความคิดใด ๆ ในการทำสิ่งนี้ให้สำเร็จ
คำตอบ
นี้เป็นไปไม่ได้
ระบบประเภทคงที่ของ TypeScript (ซึ่งรวมถึงmyTypeคำจำกัดความและคำอธิบายประกอบประเภทของคุณ) จะถูกลบเมื่อโค้ดถูกปล่อยออกมาเป็น JavaScript JavaScript คือสิ่งที่รันรันไทม์ ที่รันไทม์ทั้งหมดที่คุณสามารถเข้าถึงมีค่า การลบประเภทหมายความว่ารหัสของคุณด้านบนจะกลายเป็นดังนี้:
const passingType = (t) => {
const x = {};
};
passingType(myType);
มีค่าไม่มีชื่อเป็นส่งผ่านไปยังmyTypepassingType
และเนื่องจากประเภท typescript ไม่อยู่เป็นค่าที่รันไทม์ไม่มี "ประเภทของประเภท" Typeชอบสิ่งที่คุณกำลังโทร ดังนั้นแนวทางนี้จึงไม่สามารถทำได้โดยตรง
แทนที่จะคิดถึงการส่ง "type" ไปยังฟังก์ชันที่รันไทม์ซึ่งไม่เกิดผลดีที่สุดควรคิดเฉพาะเกี่ยวกับสิ่งที่คุณต้องการให้เกิดขึ้นที่รันไทม์ใน JavaScript บริสุทธิ์จากนั้นจึงเขียนประเภทเพื่อรองรับสิ่งนั้น
คุณต้องการทำอะไรกับ "type" ที่รันไทม์? คุณต้องการใช้เพื่อตรวจสอบว่าค่าเป็นประเภทนั้นหรือไม่? จากนั้นแทนที่จะส่งประเภทคุณอาจต้องการส่งผ่านในฟังก์ชัน type guard :
type Guard<T> = (x: any) => x is T;
const passingType = <T,>(t: Guard<T>) => {
if (t(undefined)) {
console.log("undefined IS of the guarded type T");
} else {
console.log("undefined is NOT of the guarded type T");
}
}
และคุณสามารถใช้มันได้ดังนี้:
function isUndefined(x: any): x is undefined {
return typeof x === "undefined";
}
passingType(isUndefined); // undefined IS of the guarded type T
function isNumber(x: any): x is number {
return typeof x === "number";
}
passingType(isNumber); // undefined IS NOT of the guarded type T
function isNumberOrUndefined(x: any): x is number | undefined {
return isNumber(x) || isUndefined(x);
}
passingType(isNumberOrUndefined); // undefined IS of the guarded type T
กรณีการใช้งานจริงของคุณจะผลักดันข้อกำหนดสำหรับอาร์กิวเมนต์passingTypeควรมีลักษณะอย่างไร อาจเป็นโครงสร้างข้อมูลทั้งหมดที่แสดงถึงสิ่งต่างๆที่คุณต้องการทำด้วย "type" ในรันไทม์ ดังนั้นแม้ว่าตัวอย่างการ์ดประเภทนี้จะไม่ได้ผลสำหรับคุณ แต่ก็เป็นไปได้ว่าจะมีอย่างอื่น
แต่อีกครั้งคำตอบสั้น ๆ คือระบบประเภทสแตติกของ TypeScript ถูกลบดังนั้นจึงเป็นไปไม่ได้ที่จะอ้างถึงประเภทโดยตรงที่รันไทม์
ลิงก์สนามเด็กเล่นไปยังรหัส
ใช้ยาชื่อสามัญแทน อาร์กิวเมนต์ประเภทมีไวยากรณ์ที่แตกต่างจากอาร์กิวเมนต์ JS ที่ปล่อยออกมา ตัวอย่างเช่น:
type TheType = |
{ foo: string } |
{ bar: string };
const passingType = <T extends TheType>(obj: T) => {
return { ...obj };
};
const result = passingType({ foo: 'foo' });
สิ่งนี้ส่งผลresultให้วัตถุใหม่ที่สร้างขึ้นภายในฟังก์ชันถูกพิมพ์อย่างถูกต้องเป็น{ foo: string }.