[英]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"
之類的鍵對string
( ERRORS
是)進行索引,並且它不允許這樣做。 它將認為該屬性的類型為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
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.