Transcripción: Proveer de tipo genérico, matriz vs tupla de datos de base de datos

0

Pregunta

Estoy usando el mssql biblioteca que tiene este interface:

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

Tengo una función que obtiene los datos de una base de datos y devuelve una matriz de IRecordSet<T>, por lo que es un array de arrays que contienen el tipo genérico <T>. Esto se parece a:

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

import { IRecordSet } from 'mssql'

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

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

Ahora necesito una función que llama a getData()y me gustaría escriba el real devuelve los datos al proporcionar el tipo genérico en IRecordSet<T>.

Sé que esto no funciona, pero esto es lo que tengo ahora mismo:

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]

  // ...
}

El manuscrito está diciendo:

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

Entiendo que estos errores, pero no sé cómo tipo de la myData, firstBook & cars variables de uso de las interfaces definidas (BookData & CarData).

Lo que debe type BooksAndCars = Data<[BookData, CarData]> ser..?

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

Mejor respuesta

1

Parece que quieres BooksAndCars para ser una tupla de dos elementos de diferentes tipos:

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

Pero el getData() la función devuelve un Promise<Data<any>>o, equivalentemente, un Promise<Array<IRecordSet<any>>>. Y, lamentablemente, para el caso de uso, que significa myData será de tipo Array<IRecordSet<any>>, una matriz de longitud desconocida, donde el primer y segundo elementos de distinguir los tipos. Se considera un tipo de error en la Transcripción para asignar un desconocido-longitud homogénea de la matriz a una de dos elementos heterogéneos tupla, ya que el compilador no puede garantizar que la matriz devuelta tiene exactamente dos elementos: el tipo de derecho en el orden correcto.

Si usted está seguro de que lo que estás haciendo es seguro, y quieren renunciar tipo de comprobación por el compilador, puede utilizar un tipo de afirmación que acaba de decirle al compilador que no se preocupe acerca de ella:

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]

  // ...
}

Creo que un tipo de afirmación es probablemente el camino a seguir aquí porque getData()'s tipo de retorno implica la any tipo , por lo que ya se dio por vencido en el tipo de garantías de seguridad. No es mucho peor que asumir que usted está volviendo una tupla que se supone que estás volviendo una matriz de BookData | CarData. Tienes que tener cuidado ya sea de manera que su consulta sql realmente devolverá los datos de la longitud y tipos que usted espera.

Si usted hizo realmente se preocupan por la seguridad de tipos, tendría que escribir código en tiempo de ejecución para comprobar la longitud y tipos, y entonces podríamos hablar de cómo hacer que el compilador de reconocer que sus cheques deben estrecho de Promise<Data<object>> (o algo) a BooksAndCars. Pero no voy a ir bajando de esa ruta aquí, ya que está fuera del ámbito de la pregunta, tal como solicitó.

Patio enlace a código

2021-11-24 20:25:18

En otros idiomas

Esta página está en otros idiomas

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