Mașina de scris: Furnizarea de tip generic, matrice vs tuplu, pentru baza de date

0

Problema

Eu sunt, folosind mssql bibliotecă care are această interface:

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

Am o funcție care primește datele de la o bază de date și returnează o matrice de IRecordSet<T>asta e , deci o serie de tablouri care conțin tip generic <T>. Acest lucru arata ca:

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

import { IRecordSet } from 'mssql'

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

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

Acum am nevoie de o funcție care solicită getData()și aș vrea să tastați efectivă a revenit de date prin furnizarea de tip generic în IRecordSet<T>.

Știu că acest lucru nu funcționează, dar acest lucru este ceea ce am eu acum:

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]

  // ...
}

Mașina de scris este zicând:

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

Am înțeles că aceste erori, dar nu știu cum să tastați myData, firstBook & cars variabile folosind interfețe definite (BookData & CarData).

Ce ar trebui să type BooksAndCars = Data<[BookData, CarData]> fi..?

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

Cel mai bun răspuns

1

Se pare ca vrei BooksAndCars pentru a fi un tuplu din exact două elemente de tipuri diferite:

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

Dar getData() funcția returnează un Promise<Data<any>>sau un echivalent Promise<Array<IRecordSet<any>>>. Și, din păcate, pentru cazul dumneavoastră de utilizare, care înseamnă myData va fi de tip Array<IRecordSet<any>>, o serie de necunoscute lungime în cazul în care prima și a doua elemente sunt imposibil de distins de tipuri. Acesta este considerat un tip de eroare la mașina de Scris pentru tine de a atribui astfel de un necunoscut-lungimea matrice omogenă a două elemente eterogene tuplu, deoarece compilatorul nu poate garanta că a revenit matrice are exact două elemente de tipul corect în ordinea corectă.

Dacă tu ești sigur că ceea ce faci este în siguranță, și doresc să renunțe la verificarea tipului de compilator, puteți utiliza un tip de afirmație pentru a spune compilatorului să nu vă faceți griji despre asta:

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]

  // ...
}

Cred că un tip de afirmație este, probabil, modul de a merge, pentru că aici getData()intoarcerea tip implică în any tip așa că deja ai renunțat la tipul de garanții de securitate. Nu e mult mai rău să presupunem că vă sunt obtinerea înapoi un tuplu decât să presupunem că vei primi înapoi o serie de BookData | CarData. Trebuie să fii atent oricum asta interogare sql într-adevăr va reveni cu date de lungimea și tipuri-ai aștepta.

Dacă ai făcut într-adevăr pasă de tip siguranță, ai scrie runtime cod pentru a verifica lungimea și tipuri, și atunci am putea vorbi despre modul de a face compilatorul recunoaște că verificările ar trebui să îngustă de Promise<Data<object>> (sau ceva) să BooksAndCars. Dar nu voi merge pe acest traseu aici, deoarece este în afara domeniului de aplicare pentru întrebarea cât a cerut.

Loc de joaca link-ul de la cod

2021-11-24 20:25:18

În alte limbi

Această pagină este în alte limbi

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