Transcrito: Prestação de tipo genérico, de matriz vs tupla, para o banco de dados

0

Pergunta

Eu estou usando o mssql biblioteca que tem este interface:

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

Eu tenho uma função que recebe dados de um banco de dados e retorna uma matriz de IRecordSet<T>, de modo que é uma matriz de matrizes que contêm o tipo genérico <T>. Este aspecto:

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

import { IRecordSet } from 'mssql'

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

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

Agora eu preciso de uma função que chama getData()e eu gostaria de o real voltou de dados, fornecendo o tipo genérico em IRecordSet<T>.

Eu sei que isso não funciona, mas isso é o que eu tenho agora:

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]

  // ...
}

O TypeScript é dizendo:

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

Eu entendo esses erros, mas eu não sei como escrever o myData, firstBook & cars variáveis usando as interfaces definidas (BookData & CarData).

O que deve type BooksAndCars = Data<[BookData, CarData]> será..?

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

Melhor resposta

1

Parece que você quer BooksAndCars para ser uma tupla de dois elementos de tipos diferentes:

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

Mas o getData() a função retorna um Promise<Data<any>>ou equivalentemente um Promise<Array<IRecordSet<any>>>. E, infelizmente, para o caso de uso, o que significa que myData será do tipo Array<IRecordSet<any>>, uma matriz de comprimento desconhecido, onde o primeiro e o segundo elementos são indistinguíveis tipos. Ele é considerado um tipo de erro no arquivo TypeScript para lhe atribuir tal desconhecido-comprimento homogênea da matriz para um de dois elementos heterogêneos tupla, desde que o compilador não pode garantir que a matriz retornada possui exatamente dois elementos do tipo direito na ordem certa.

Se você tem certeza de que o que você está fazendo é seguro, e quer abster-se de verificação de tipo pelo compilador, você pode usar um tipo de declaração apenas para dizer ao compilador para não se preocupar com isso:

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]

  // ...
}

Eu acho que um tipo de afirmação é provavelmente a forma de o fazer aqui, porque getData()'s tipo de retorno envolve o any digite , assim você já deu até no tipo de garantias de segurança. Não é muito pior do que assumir que você está recebendo de volta uma tupla que é assumir que você está recebendo de volta uma matriz de BookData | CarData. Você tem que ser cuidadoso, de qualquer forma que a consulta sql realmente retornará os dados de comprimento e tipos que você espera.

Se você fez realmente se preocupam com o tipo de segurança, você teria que escrever o código de tempo de execução para verificar o comprimento e tipos, e, em seguida, nós poderíamos falar sobre como fazer com que o compilador reconhece que os cheques devem estreito de Promise<Data<object>> (ou algo assim) para BooksAndCars. Mas eu não quero ir por esse caminho aqui, já que é fora do escopo para a pergunta que pediu.

Parque infantil link para o código de

2021-11-24 20:25:18

Em outros idiomas

Esta página está em outros idiomas

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