Dattiloscritto: Fornitura di tipo generico, array vs tupla, per database dati

0

Domanda

Sto usando il mssql libreria che ha questo interface:

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

Ho una funzione che riceve i dati da un database e restituisce un array di IRecordSet<T>una matrice di matrici che contengono il tipo generico <T>. Questo appare come:

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

import { IRecordSet } from 'mssql'

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

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

Ora ho bisogno di una funzione che chiama getData()e mi piacerebbe tipo effettiva dati restituiti da fornire il tipo generico in IRecordSet<T>.

So che questo non funziona, ma questo è quello che ho adesso:

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]

  // ...
}

Dattiloscritto dice:

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

Capisco questi errori, ma non so come tipo il myData, firstBook & cars variabili utilizzando le interfacce definite (BookData & CarData).

Che cosa dovrebbe type BooksAndCars = Data<[BookData, CarData]> essere..?

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

Migliore risposta

1

Sembra che desideri BooksAndCars per essere una tupla di esattamente due elementi di diversi tipi:

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

Ma il getData() la funzione restituisce un Promise<Data<any>>o, equivalentemente, un Promise<Array<IRecordSet<any>>>. E purtroppo per il vostro caso d'uso, che significa myData sarà del tipo Array<IRecordSet<any>>un array di lunghezza sconosciuta, dove il primo e il secondo elementi sono indistinguibili tipi. È considerato un errore di tipo a Macchina per attribuire tale unknown-lunghezza omogenea array di due elementi eterogenei tupla, dato che il compilatore non è in grado di garantire che la matrice restituita ha esattamente due elementi del tipo giusto nel giusto ordine.

Se si è sicuri che quello che stai facendo è sicuro, e vuole rinunciare al tipo di controllo da parte del compilatore, è possibile utilizzare un tipo di asserzione basta dire al compilatore di non preoccuparsi:

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]

  // ...
}

Penso che un tipo di affermazione è probabilmente il modo di andare qui, perché getData()'s tipo di ritorno prevede la any tipo così è già dato sul tipo di garanzie di sicurezza. Non è molto peggio di assumere che stai ricevendo indietro una tupla che è di assumere che stai ricevendo un array di BookData | CarData. Bisogna stare attenti in ogni modo che la query sql davvero restituirà i dati della durata e del tipo previsto.

Se si ha veramente a cuore il tipo di sicurezza, è necessario scrivere codice a runtime per controllare la lunghezza e tipi, e poi potremmo parlare di come fare il compilatore riconosce che i controlli dovrebbero stretti da Promise<Data<object>> (o qualcosa) BooksAndCars. Ma non voglio andare a nanna qui, dal momento che è fuori portata per la domanda, come chiesto.

Giochi link al codice

2021-11-24 20:25:18

In altre lingue

Questa pagina è in altre lingue

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