typescript - การพิมพ์ฟังก์ชันที่ห่อทุกอาร์กิวเมนต์เป็นอาร์เรย์
ฉันกำลังพยายามพิมพ์ฟังก์ชันอย่างถูกต้องที่รับอาร์กิวเมนต์และห่อมันเป็นอาร์เรย์ อย่างไรก็ตาม ฉันไม่สามารถทำให้การพิมพ์ทำงานได้อย่างถูกต้อง
function wrapInArray<T>(data:T):T extends Array<infer K>? K[]: T[]{
return Array.isArray(data)? [...data]:[data]
// ^ Type '(T & any[])[number][]' is not assignable to type 'T extends (infer K)[] ? K[] : T[]'
}
const a = wrapInArray('test') // string[]
const b = wrapInArray([1,2]) // number[]
ฟังก์ชันทำงานถูกต้อง และถ้าฉันลองใช้ฟังก์ชัน TypeScript จะสรุปประเภทการคืนค่าถูกต้อง ตอนนี้ฉันสงสัยว่าทำไมฉันถึงได้รับข้อผิดพลาดในประกาศฟังก์ชันเอง
สนามเด็กเล่น TS
คำตอบ #1
นี่เป็นเพราะลักษณะของฟังก์ชัน isArray ซึ่งถูกพิมพ์แบบนี้:
isArray(arg: any): arg is any[];
ดังนั้นเมื่อมันเป็นจริง arg is any[] หมายความว่าข้อมูลเป็น any[] แต่คุณก็ได้บอกว่ามันเป็น T ดังนั้นคุณจะได้ T & any[]...
แล้วถ้าเป็นแบบนี้ล่ะ (ไม่จำเป็นต้องมีการโอเวอร์โหลดและโบนัส เราไม่จำเป็นต้องระบุว่าฟังก์ชันส่งค่ากลับอะไร เราจะปล่อยให้ Typescript สรุปให้เราก็ได้):
function wrapInArray<T>(data: T | T[]){ //function wrapInArray<T>(data: T | T[]): T[]
if (Array.isArray(data)) {
// (parameter) data: T[]
// T was either T | T[] but it's an array, we're left with only T[]
return [...data]
} else {
// (parameter) data: T
// data was either T | T[] but it's not an array so we're left with T
return [data] // we return [T]
}
}
const a = wrapInArray('test') // string[]
const b = wrapInArray([1,2]) // number[]
สนามเด็กเล่น TS
คำตอบ #2
คุณสามารถลองใช้การโอเวอร์โหลดฟังก์ชันได้:
function wrapInArray<T extends any[]>(data: T): T;
function wrapInArray<T>(data: T): T[];
function wrapInArray<T>(data: T):T | T[]{
return Array.isArray(data)? [...data]:[data]
}
const a = wrapInArray('test') // string[]
const b = wrapInArray([1,2]) // number[]
สนามเด็กเล่น TS
