Strojopis: Poskytuje obecný typ, pole vs n-tice, pro databáze dat

0

Otázka

Používám mssql knihovna, která má tento interface:

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

Já mám funkci, která získá data z databáze a vrací pole IRecordSet<T>,, tak, že je pole polí, které obsahují obecný typ <T>. To vypadá jako:

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

import { IRecordSet } from 'mssql'

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

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

Teď jsem třeba funkce, která volá getData()a rád bych, aby typ skutečná vrácená data tím, že poskytuje obecný typ IRecordSet<T>.

Vím, že to nefunguje, ale to je to, co mám teď:

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]

  // ...
}

Strojopis říká:

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

Chápu tyto chyby, ale nevím, jak zadat myData, firstBook a cars proměnných pomocí rozhraní definované (BookData a CarData).

Co by měl type BooksAndCars = Data<[BookData, CarData]> být..?

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

Nejlepší odpověď

1

Vypadá to, že chceš BooksAndCars být n-tice přesně dva prvky z různých typů:

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

Ale getData() funkce vrátí Promise<Data<any>>nebo ekvivalentně jako Promise<Array<IRecordSet<any>>>. A bohužel, pro váš případ použití, to znamená, že myData bude mít typ Array<IRecordSet<any>>, pole neznámé délky, kde první a druhé prvky jsou k nerozeznání typy. To je považováno za typ chyby na psacím Stroji pro vás přiřadit takové neznámé-délka homogenní pole na dvě heterogenní prvek n-tice, protože kompilátor nemůže zaručit, že vrácené pole má přesně dva prvky typu ve správném pořadí.

Pokud jste si jisti, že to, co děláte, je v bezpečí, a chtěla vzdát kontrola typu kompilátorem, můžete použít typ tvrzení jen říci kompilátoru a ne se starat 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 tvrzení je pravděpodobně způsob, jak jít sem, protože getData()je návratový typ zahrnuje v any typ takže jste již vzdal typ záruky bezpečnosti. Není to mnohem horší, předpokládat, že jste dostat se zpátky n-tice, než je předpokládat, že jste dostat se zpátky pole BookData | CarData. Musíte být opatrní, a to buď způsobem, že sql dotaz opravdu vrátí data, délky a typy, které očekáváte.

Pokud jste opravdu péči o typu bezpečnosti, byste měli psát runtime kód pro kontrolu délky a typy, a pak bychom mohli mluvit o tom, jak kompilátor zjistí, že kontroly by se měly úzké z Promise<Data<object>> (nebo tak něco) BooksAndCars. Ale já nechci jít dolů, že cesta, protože to je prostor pro otázku, jak se zeptal.

Hřiště odkaz na kód

2021-11-24 20:25:18

V jiných jazycích

Tato stránka je v jiných jazycích

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