Типскрипт: Zapewnienie powszechnego typu, tablica przeciwko tkę, dla danych z bazy danych

0

Pytanie

Używam biblioteki mssql, w której jest to interface:

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

Mam funkcję, która pobiera dane z bazy danych i zwraca tablicę IRecordSet<T>tak , że jest to tablica tablic, które zawierają uniwersalny typ <T>. Wygląda to tak:

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

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 potrzebuję funkcji, która powoduje getData()i chciałbym wprowadzić rzeczywiste dane zwrócone, podając ogólny typ w IRecordSet<T>.

Wiem, że to nie działa, ale to jest to, co mam 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]

  // ...
}

Maszynopisu tekst mówi:

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

Rozumiem te błędy, ale nie wiem, jak wpisać myData, firstBook & cars zmienne, które także używają określone interfejsy (BookData & CarData).

Co powinno type BooksAndCars = Data<[BookData, CarData]> być...?

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

Najlepsza odpowiedź

1

Wygląda na to, że chcesz BooksAndCars być konwoju dokładnie z dwóch elementów różnych typów:

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

Ale w getData() funkcja zwraca Promise<Data<any>>lub, co jest równoważne, a Promise<Array<IRecordSet<any>>>. I, niestety, dla opcji użycia to oznacza myData będzie mieć typ Array<IRecordSet<any>>, tablica nieznanej długości, w którym pierwszy i drugi elementy mają niewiem typy. W TypeScript jest błędem typu nadanie takiego jednolitego tablicy nieznanej długości двухэлементному гетерогенному кортежу, ponieważ kompilator nie może zagwarantować, że zwrócona tablica zawiera dokładnie dwa elementy właściwego typu w odpowiedniej kolejności.

Jeśli jesteś pewien, że to, co robisz, bezpieczne, i chcesz zrezygnować z kontroli typu kompilator, można użyć zatwierdzenie typu, aby po prostu powiedzieć, że kompilator, aby nie zastanawiałem się nad tym:

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]

  // ...
}

Myślę, że stwierdzenie typu, prawdopodobnie, jest dobrym rozwiązaniem tutaj, bo getData()typ zwracanej wartości zawiera w sobie any wprowadź, to znaczy, że już zrezygnowali z gwarancji bezpieczeństwa typu. Nie wiele gorzej przypuszczać, że zwracasz orszak, niż zakładać, że wracasz do tablicy BookData | CarData. W każdym razie trzeba być ostrożnym, aby twoje zapytanie sql naprawdę oddawał dane oczekiwanej długości i typów.

Gdyby naprawdę troszczyli się o bezpieczeństwo typów, można by napisali kod do czasu wykonywania kontroli długości i typów, a następnie moglibyśmy porozmawiać o tym, jak zmusić kompilator rozpoznać, że twoje kontroli powinny сузиться z Promise<Data<object>> (lub coś w tym rodzaju), aby BooksAndCars. Ale nie będę się tu na tej drodze, tak jak to wykracza poza zakres zadanego pytania.

Link do zabaw dla kodu

2021-11-24 20:25:18

W innych językach

Ta strona jest w innych językach

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