簡體   English   中英

TypeScript:使用自定義驗證值擴展鍵

[英]TypeScript: extend keys with custom validation values

我正在嘗試擴展類鍵並設置自定義值以進行驗證。

class FindUserDto {

  readonly _id?: string | object;
  readonly email?: string;
  readonly firstName?: string;
  readonly lastName?: string;
}

我需要的是創建SortBy類,該類應該從FindUserDto獲取鍵並驗證'ASC''DESC'作為傳入值。 像這樣的東西。

class SortBy {
  readonly email: 'ASC' | 'DESC';
  readonly firstName: 'ASC' | 'DESC';
  readonly lastName: 'ASC' | 'DESC';
}

但我想避免復制和粘貼,這就是為什么我要與打字稿作斗爭來處理它。

我試圖像這樣動態設置鍵[K in keyof FindUserDto]或這個[key: K]其中K extends {[T in keyof FindUserDto]}但它不起作用。 Typescript 不允許實現這樣的流程。

現在最簡單的解決方案是通過在內部傳遞類型來升級FindUserDto類:

class FindUserDto<T>{
  _id?: T;
  readonly email?: T;
  readonly firstName?: T;
  readonly lastName?: T;
}


class SortBy extends FindUserDto<'ASC' | 'DESC'> {

}

但我想得到一個更可重用的解決方案。 有人嘗試制作類似的東西嗎?

您可以將Record類型與keyof T結合使用。 使用這個SortBy不會是一個類,它將是一個類型別名,你可以使用任何對象字面量來實現它:

class FindUserDto {
    readonly _id?: string | object;
    readonly email?: string;
    readonly firstName?: string;
    readonly lastName?: string;
}

type SortBy = Record<keyof FindUserDto, 'ASC' | 'DESC'> 
// type SortBy = Record<Exclude<keyof FindUserDto, "_id">, 'ASC' | 'DESC'> // or remove _id 
let sortBy: SortBy = {
    _id: "ASC",
    email: "DESC",
    firstName: "DESC",
    lastName: "ASC"
}

或者你也可以將它作為一個類來實現,但你必須重新聲明這些字段(盡管編譯器確保你重新聲明它們):

class SortBy implements Record<keyof FindUserDto, 'ASC' | 'DESC' | undefined>  {
    _id: "ASC" | "DESC"| undefined;
    email: "ASC" | "DESC"| undefined;
    firstName: "ASC" | "DESC"| undefined;
    lastName: "ASC" | "DESC"| undefined;
}

如果您不重新聲明所有字段,您還可以創建一個虛擬類,為了編譯器的利益而假裝實現這些字段:

function sortByClass<T>() : new () => Record<keyof T, 'ASC' | 'DESC' | undefined> {
    return class {} as any
}
class SortBy extends sortByClass<FindUserDto>() {
}

注意:由於字段未初始化,我添加了| undefined | undefined為字段類型,以保持字段類型與實際可能性保持一致。 這僅在您使用stricyNullChecks

class FindUserDto {
  readonly _id?: string | object;
  readonly email?: string;
  readonly firstName?: string;
  readonly lastName?: string;
}

type Sortable <T> = {
   [P in keyof T]: 'ASC' | 'DESC';
};

let a: Sortable<FindUserDto>; 

a = { email: 'ASC', firstName: 'DESC', lastName: 'ASC' };

// a = { email: 'ASC', firstName: 'DESC', lastName: 'ASC123' }; //error

這是enums的另一個解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM