TypeScript:ในกรณีที่ประเภททั่วไป,อาเรย์กับ tuple สำหรับฐานข้อมูลข้อมูล

0

คำถาม

ฉันใช้ mssql องสมุดซึ่งนี้ interface:

export interface IRecordSet<T> extends Array<T> {
    columns: IColumnMetadata;
    toTable(name?: string): Table;
}

ฉันมีฟังก์ชันที่จะได้ข้อมูลจากฐานข้อมูลและจะได้ค่าเป็นตารางคู่ลำดับของ IRecordSet<T>ดังนั้นนั่นเป็นอาเรย์ของ arrays ซึ่งมีคนประเภททั่วไป <T>. นี่ดูเหมือนว่า:

[[{}, {}, ...], [{}, {}, ...], ...]

import { IRecordSet } from 'mssql'

type Data<T> = Array<IRecordSet<T>>

async function getData (sql: string): Promise<Data<any>> {
  // connect to db, run sql
  return []
}

ตอนนี้ฉันต้องการฟังก์ชันที่โทรมา getData()และฉันอยากจะประเภทที่แท้จริงกลับหาข้อมูลโดยให้แก่คนพิมพ์ทั่วไป IRecordSet<T>.

ฉันรู้ว่านี่มันไม่ทำงานแต่นี่คือสิ่งที่ฉันมีตอนนี้:

interface BookData {
  name: string
  author: string
}
interface CarData {
  make: string
  model: string
}

type BooksAndCars = Data<[BookData, CarData]>

async function getBooksAndCars (): Promise<void> {
  const myData: BooksAndCars = await getData(`
    SELECT name, author FROM Books;
    SELECT make, model FROM Cars;
  `)

  const firstBook: BookData = myData[0][0]
  const cars: CarData[] = myData[1]

  // ...
}

TypeScript คือบอกว่า:

  • Type '[BookData, CarData]' is not assignable to type 'BookData'.
  • Type 'IRecordSet<[BookData, CarData]>' is not assignable to type 'CarData[]'.

ฉันเข้าใจว่าพวกนี้เกิดข้อผิดพลาดแต่ฉันไม่รู้ว่าต้องประเภทที่ myData, firstBook & cars ตัวแปรใช้ส่วนเชื่อมต่อถูกกำหนด(BookData & CarData).

สิ่งที่ควร type BooksAndCars = Data<[BookData, CarData]> เป็น..?

types typescript
2021-11-23 19:20:57
1

คำตอบที่ดีที่สุด

1

มันดูเหมือนว่าคุณต้องการ BooksAndCars ต้องเป็น tuple ของแน่นอนสองส่วนประกอบที่แตกต่างกันประเภท:

type BooksAndCars = [IRecordSet<BookData>, IRecordSet<CarData>];

แต่ getData() ฟังก์ชันจะได้ค่าเป็น Promise<Data<any>>หรือ equivalently น Promise<Array<IRecordSet<any>>>. และโชคไม่ดีสำหรับของคุณใช้กรณีนี้,นั่นหมายความว่า myData จะเป็นประเภท Array<IRecordSet<any>>เป็นอาเรย์ของที่ไม่รู้จักความยาวที่คนแรกและครั้งที่สองส่วนประกอบของ indistinguishable ยชนิด มันคือพิจารณาว่าเป็นชนิดข้อผิดพลาดใน TypeScript สำหรับคุณต้องกำหนดเช่นที่ไม่รู้จัก-ความยาว homogeneous อาเรย์จะเป็นสองธาตุ heterogeneous tuple,ตั้งแต่คอมไพเลอร์ไม่สามารถรับประกันว่าคนกลับมาอาเรย์มีสองส่วนประกอบของที่ถูกต้องพิมพ์ที่ถูกต้องคำสั่ง

ถ้า คุณ มั่นใจว่านั่นเป็นสิ่งที่คุณกำลังทำอะไรปลอดภัยและอยาก forgo ประเภทเช็คที่คอมไพเลอร์,คุณสามารถใช้เป็น ประเภท assertion ต้องแค่บอกคอมไพเลอร์ไม่ต้องห่วงเกี่ยวกับมัน:

async function getBooksAndCars(): Promise<void> {
  const myData = await getData(`
    SELECT name, author FROM Books;
    SELECT make, model FROM Cars;
  `) as BooksAndCars

  const firstBook = myData[0][0];
  const cars: CarData[] = myData[1]

  // ...
}

ฉันคิดว่าเป็นประเภท assertion อาจจะเป็นหนทางที่ถูกต้องอยู่ที่นี่เพราะ getData()'s คืนเกี่ยวข้องกับประเภท ที่ any ประเภท ดังนั้นคุณแล้วให้อยู่ประเภทความปลอดภัยรับประกัน มันไม่แย่กว่านี้อีกที่จะสันนิษฐานว่าคุณกำลังจะกลับมาเป็น tuple ว่ามันคือการเดาว่าคุณกำลังจะกลับเป็นตารางคู่ลำดับของ BookData | CarData. คุณต้องระวังตัวให้มากขึ้นด้วเหมือนกันทางของคุณร้องขอแบบ sql จริงก็ต้องกลับข้อมูลของความยาวและชนิดคาดไม่ถึง

ถ้าคุณทำจริสนใจเรื่องประเภทความปลอดภัยคุณจะเขียน runtime รหัสเพื่อตรวจดูความยาวและประเภทและจากนั้นเราจะสามารถพูดคุยเกี่ยวกับวิธีการทำคอมไพเลอร์รู้จักว่าของคุณเช็คควรจะ จำกัดวPromise<Data<object>> (หรือบางอย่าง)เพื่ BooksAndCars. แต่ฉันจะไม่ไปลงที่เส้นทางอยู่ที่นี่ตั้งแต่มันออกจากขอบเขตสำหรับคำถามที่ถาม

สนามเด็กเล่นเชื่อมโยงไปยังนรหัส

2021-11-24 20:25:18

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่