簡體   English   中英

Typescript 接口值作為枚舉或記錄

[英]Typescript interface value as enum or Record

假設我有一些 object 可以將key作為字符串,將value作為enum或 object,將鍵和值作為枚舉。

類型

export enum ERRORS {
  ERROR1 = 'Error1',
  ERROR2 = 'Error2',
}

export type ErrorType = 'blue' | 'green';

export interface ErrorByCode {
  [key: string]: ERRORS | Record<ErrorType, ERRORS>;
}

代碼

const ERRORS_BY_CODE: ErrorByCode = {
  default: ERRORS.ERROR1,
  '01': ERRORS.ERROR2,

  '2': {
    blue: ERRORS.ERROR1,
    green: ERRORS.ERROR2,
  },
};

const errorResolver = ({code, type}: {code: string; type: ERRORS}) => {
    const errorMessage =
    (ERRORS_BY_CODE?.[code] || ERRORS_BY_CODE?.[code]?.[type]) ??
    ERRORS_COMPONENTS_BY_CODE.default;

    return errorMessage
};


console.log(errorResolver({code: '01', type: 'blue'}))



但是我在ERRORS_BY_CODE?.[code]?.[type]下出現 ts 錯誤,因為“ErrorType”類型的表達式不能用於索引類型“ERRORS | 記錄<錯誤類型,錯誤>'。 類型 'ERRORS_BY_CODE | 上不存在屬性'藍色' 記錄<InsuranceType,ERROR_COMPONENTS>'。

編譯器不希望任何人嘗試使用"blue"之類的鍵對stringERRORS是)進行索引,並且它不允許這樣做。 它將認為該屬性的類型為any ,並給出編譯錯誤:

function nope(str: string) {
    str.blue // error! Property 'blue' does not exist on type 'string'
}

如果一個值的類型是string和其他東西的聯合,編譯器也會對這樣的索引不滿意,因為它可能是它所知道的所有string

function stillNope(uni: string | { blue: number }) {
    uni.blue // error! Property 'blue' does not exist on type 'string'
}

可選鏈接不能解決這個問題。 即使您使用?. 而不是. . 這種禁止是故意的; 有關詳細信息,請參閱microsoft/TypeScript#33736


如果要訪問聯合類型上的屬性,其中至少有一個聯合成員不知道具有該屬性,則需要使用其他形式的類型保護。 一種方法是使用typeof保護

function typeofGuard(
  uni: ERRORS | { blue: ERRORS, green: ERRORS }, 
  type: ErrorType
) {
    const errors = typeof uni === "string" ? uni : uni[type];
}

另一種可能性是將您的工會表示為工會的每個成員在ErrorType鍵上都有已知行為的工會。 而不是ERRORS ,這是一個在ErrorType沒有已知行為的string ,您可以將其設為ERRORS & {[P in ErrorType]?: undefined } 含義:它是ERRORS ,如果您使用ErrorType鍵對其進行索引,您將獲得一個undefined的屬性。 這也會使您的錯誤 go 消失:

function exclusiveUnion(
    uni: (ERRORS & { [P in ErrorType]?: undefined }) | (Record<ErrorType, ERRORS>),
    type: ErrorType
) {
    const errors = uni[type]; // ERRORS | undefined
}

Playground 代碼鏈接

暫無
暫無

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

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