Záznam: Poskytuje všeobecný typ, pole vs n-tice, pre databázu údajov

0

Otázka

Ja používam mssql knižnica, ktorá má tento interface:

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

Mám funkciu, ktorá dostane údajov z databázy a vracia pole IRecordSet<T>tak to je pole polí, ktoré obsahujú všeobecný typ <T>. To vyzerá:

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

import { IRecordSet } from 'mssql'

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

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

Teraz potrebujem funkciu, ktorá hovory getData()a ja by som chcel typ skutočné vrátil údajov poskytnutím všeobecný typ IRecordSet<T>.

Viem, že to nefunguje, ale to je to, čo som práve teraz:

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]

  // ...
}

Záznam hovorí:

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

Chápem, že tieto chyby, ale neviem, ako písať myData, firstBook & cars premenné pomocou rozhrania definované (BookData & CarData).

Čo by type BooksAndCars = Data<[BookData, CarData]> byť..?

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

Najlepšiu odpoveď

1

Vyzerá to ako chcete, BooksAndCars byť n-tice presne dva prvky rôznych typov:

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

Ale getData() funkcia vráti Promise<Data<any>>alebo equivalently a Promise<Array<IRecordSet<any>>>. A bohužiaľ pre vaše použitie prípade to znamená, že myData bude typu Array<IRecordSet<any>>množstvo neznámej dĺžky, kde prvý a druhý prvky sú na nerozoznanie typy. To je považované za typ chyba v Strojom pre vás priradiť ako neznámy-dĺžka homogénne pole na dve-prvok heterogénne n-tice, pretože kompilátor nemôže zaručiť, že sa vrátil pole má presne dva prvky správneho typu v správnom poradí.

Ak ste si istí, že to, čo robíte, je v bezpečí, a chcú vzdať typu kontroly prekladačom, môžete použiť typ tvrdenie len povedať, kompilátor nebude sa starať o to:

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]

  // ...
}

Myslím, že typ tvrdenie je pravdepodobne spôsob, ako ísť, pretože tu getData()"s priznanie typ zahŕňa v any typ , takže si už dal na typ bezpečnostné záruky. To nie je oveľa horšie predpokladať, že ste sa dostať späť n-tice, ako je to predstavte si, že ste ste dostať späť pole BookData | CarData. Musíte byť opatrní, a to buď tak, že vaše sql dotaz naozaj vráti údaje o dĺžke a typy, ktoré očakávate.

Ak ste si naozaj záleží, typ bezpečnosti, by ste napísať runtime kód skontrolovať dĺžku a typov, a potom by sme mohli hovoriť o tom, ako kompilátor uznať, že váš kontroly by mali úzke z Promise<Data<object>> (alebo niečo) na BooksAndCars. Ale nebudem ísť dole, že trasa tu, keďže je to mimo rozsahu na otázku, ako sa spýtal.

Ihrisko odkaz na kód

2021-11-24 20:25:18

V iných jazykoch

Táto stránka je v iných jazykoch

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