lambda - TypeScript, วิธีส่งชื่อฟิลด์สาธารณะด้วยนิพจน์ที่มีประเภท
ฉันกำลังพยายามหาวิธีส่งอาร์เรย์ของชื่อคุณสมบัติ (หรือชื่อฟิลด์) ของอ็อบเจ็กต์ที่กำหนด โดยไม่ใช้สตริงเวทย์มนตร์ที่เรียกว่า - เพราะง่ายต่อการพิมพ์ผิด! โดยพื้นฐานแล้ว ฉันกำลังมองหาบางสิ่งที่เกี่ยวข้องกับ "Expression<>" ของ C# ฉันคิดว่า
ตัวอย่างเช่น กับสตริงวิเศษ: searchFilter(model, 'searchParameter', ['id', 'name'])
เช่น พิมพ์ หรือวิธีที่ฉันต้องการเรียกฟังก์ชัน: searchFilter(model, 'searchParameter', [m => m.id, m => m.name])
เพื่อเป็นการอ้างอิง ฟังก์ชันนี้มีลักษณะประมาณนี้:
ด้วยสตริงเวทย์มนตร์: (หรือว่าฉันพยายามทำมันแบบมีการพิมพ์ประเภท)
private searchFilter(mode: Model, q: string, properties: string[]): boolean {
if (q === '') return true;
q = q.trim().toLowerCase();
for (let property of properties) {
if (vacature[property.toString()].toString().toLowerCase().indexOf(q) >= 0) {
return true;
}
}
return false;
}
typed: (หรือว่าฉันพยายามทำมันแบบ typed แต่แน่นอนว่านี่แค่คืนฟังก์ชันกลับมา.. ฉันจำเป็นต้องมี 'function expression' ที่เกี่ยวข้องตามใน C# เพื่อดึง property ที่ถูกเรียกใช้ เพื่อที่จะได้ชื่อของมัน)
private searchFilter(mode: Model, q: string, propertySelector: ((x: Model) => any | string)[]): boolean {
if (q === '') return true;
q = q.trim().toLowerCase();
for (let property of propertySelector) {
if (vacature[property.toString()].toString().toLowerCase().indexOf(q) >= 0) {
return true;
}
}
return false;
}
คำตอบ #1
คุณไม่สามารถกำจัดสตริงนั้นได้ ไม่มีสิ่งที่เรียกว่า nameof property ใน TypeScript (ตอนนี้ยังไม่มี)
อย่างไรก็ตาม สิ่งที่คุณสามารถทำได้คือพิมพ์บางสิ่งเป็นคีย์ของชนิดอื่น
แบบนี้
interface Model {
a: string,
b: number
}
function searchFilter(model: Model, q: keyof Model) { }
ผลลัพธ์ที่ได้คือ:
searchFilter(null, 'a') // works
searchFilter(null, 'b') // works
searchFilter(null, 'c') // error c is not a property of Model
คุณสามารถพิมพ์อาร์เรย์ของคุณสมบัติของชนิดข้อมูลได้เช่นนี้:
function searchArray(model: Model, q: string, properties: Array<keyof Model>) { }
searchArray(null, 'blabla', ['a', 'b'])
คำตอบ #2
Nameof ไม่มีให้ใช้งานโดยตรง แต่ฟังก์ชันนี้ถูกจำลองขึ้นมาด้วยไลบรารีของบุคคลที่สาม
คุณสามารถทำให้ได้ฟังก์ชัน nameof โดยใช้ไลบรารีของบุคคลที่สาม (https://www.npmjs.com/package/ts-nameof). คุณสามารถดูซอร์สโค้ดได้ที่นี่: https://github.com/dsherret/ts-nameof
ในกรณีนี้ ไลบรารีได้จัดเตรียมตัวเลือกหลายแบบขึ้นอยู่กับระดับของชื่อวัตถุที่คุณต้องการใช้ เช่น ชื่อของตัวแปรเอง ชื่อของเมธอด ชื่อของเมธอดพร้อมกับคลาสที่บรรจุอยู่ และอื่น ๆ (ตอนย่อจากเอกสารของไลบรารี)
ด้านล่างแสดงผลลัพธ์ของ JavaScript ที่ถูกแปลงทางซ้าย และรูปแบบเทียบเท่าของ TypeScript ทางด้านขวา
console.log("console"); // console.log(nameof(console));
console.log("log"); // console.log(nameof(console.log));
console.log("console.log"); // console.log(nameof.full(console.log));
console.log("alert.length"); // console.log(nameof.full(window.alert.length, 1));
console.log("length"); // console.log(nameof.full(window.alert.length, 2));
console.log("length"); // console.log(nameof.full(window.alert.length, -1));
console.log("alert.length"); // console.log(nameof.full(window.alert.length, -2));
console.log("window.alert.length"); // console.log(nameof.full(window.alert.length, -3));
"MyInterface"; // nameof<MyInterface>();
console.log("Array"); // console.log(nameof<Array<MyInterface>>());
"MyInnerInterface"; // nameof<MyNamespace.MyInnerInterface>();
"MyNamespace.MyInnerInterface"; // nameof.full<MyNamespace.MyInnerInterface>();
"MyInnerInterface"; // nameof.full<MyNamespace.MyInnerInterface>(1);
"Array"; // nameof.full<Array<MyInterface>>();
"prop"; // nameof<MyInterface>(o => o.prop);
สตริงเหล่านี้จะถูกแทนที่ในเวลาการแปลงโค้ด ดังนั้นจึงไม่ควรมีผลต่อประสิทธิภาพในระหว่างการรันไทม์
