TypeScript: Veritabanı verileri için genel tür, dizi vs tuple sağlama

0

Soru

Buna sahip olan mssql kütüphanesini kullanıyorum interface:

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

Bir veritabanından veri alan ve bir dizi döndüren bir işlevim var IRecordSet<T> yani bu, genel türü içeren bir dizi dizidir <T>. Bu gibi görünüyor:

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

import { IRecordSet } from 'mssql'

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

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

Şimdi çağıran bir işleve ihtiyacım var getData() Ve genel türü sağlayarak gerçek döndürülen verileri yazmak istiyorum IRecordSet<T>.

Bunun işe yaramadığını biliyorum ama şu an elimde olan bu:

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]

  // ...
}

TypeScript diyor ki:

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

Bu hataları anlıyorum, ancak nasıl yazacağımı bilmiyorum myData, firstBook & cars tanımlanan arayüzleri kullanan değişkenler (BookData & CarData).

What should type BooksAndCars = Data<[BookData, CarData]> olmak..?

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

En iyi cevabı

1

İstediğin gibi görünüyor. BooksAndCars farklı tiplerde tam olarak iki elementten oluşan bir tuple olmak:

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

Ama getData() işlev a değerini döndürür Promise<Data<any>> veya eşdeğer olarak a Promise<Array<IRecordSet<any>>>. Ve ne yazık ki kullanım durumunuz için bu şu anlama geliyor myData tip olacak Array<IRecordSet<any>>, birinci ve ikinci elemanların ayırt edilemez türlerde olduğu bilinmeyen uzunluk dizisi. Derleyici, döndürülen dizinin doğru sırayla tam olarak doğru türde iki öğeye sahip olduğunu garanti edemediğinden, bilinmeyen uzunlukta homojen bir diziyi iki öğeli heterojen bir diziye atamanız Typescript'te bir tür hatası olarak kabul edilir.

Yaptığınız şeyin güvenli olduğundan eminseniz ve derleyici tarafından tür denetiminden vazgeçmek istiyorsanız, derleyiciye bu konuda endişelenmemesini söylemek için bir tür onaylama işlemi kullanabilirsiniz:

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]

  // ...
}

Bir tür iddianın muhtemelen buraya gitmenin yolu olduğunu düşünüyorum çünkü getData()'nin dönüş tipi şunları içerir any yazın, böylece zaten tip güvenlik garantilerinden vazgeçtiniz. Bir tuple geri aldığınızı varsaymak, bir dizi geri aldığınızı varsaymaktan çok daha kötü değildir. BookData | CarData. Her iki durumda da, sql sorgunuzun gerçekten beklediğiniz uzunluk ve türdeki verileri döndüreceğine dikkat etmeniz gerekir.

Tür güvenliğini gerçekten önemsediyseniz, uzunluğu ve türleri kontrol etmek için çalışma zamanı kodu yazarsınız ve daha sonra derleyicinin kontrollerinizin daraltılması gerektiğini nasıl tanıyacağı hakkında konuşabiliriz Promise<Data<object>> (veya şeyler) BooksAndCars. Ama burada o yoldan gitmeyeceğim, çünkü sorulduğu gibi sorunun kapsamı dışında.

Oyun alanı koduna bağlantı

2021-11-24 20:25:18

Diğer dillerde

Bu sayfa diğer dillerde

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