如何使用标记字符串作为Record类型的索引



我的字符串采用特定的格式,所以我经常键入它们以确保它们是特定的格式。例如,我检查字符串是否以foo为前缀。如何使用品牌字符串作为记录的索引?

type Foo = string & { _fooBrand: undefined }
type T = Record<Foo, string>
const f = (a: T, b: Foo) => {
const c = a[b] // Type 'Foo' cannot be used as an index type.
}

我设法通过创建一些条件类型中的辅助函数来解决这个问题。然后可以使用辅助函数get(), set(), keys(), values()

export const get = <T, K extends keyof T>(obj: T, key: K): RecordValue<T> | undefined =>
(obj as any)[key] as RecordValue<T> | undefined
export const set = <T, K extends keyof T, V extends RecordValue<T>>(
obj: T,
key: K,
value: V
): CheckRecordKeyValue<T, K, V> => ((obj as any)[key] = value as any)
export const keys = <T>(obj: T): RecordKey<T>[] => Object.keys(obj) as RecordKey<T>[]
export const values = <T>(obj: T): RecordValue<T>[] => Object.values(obj) as RecordValue<T>[]
export type RecordKey<T> = T extends Record<infer K, infer V> ? K : never
export type RecordValue<T> = T extends Record<infer K, infer V>
? K extends keyof T
? V
: never
: never
export type CheckRecordKeyValue<T, K, V> = T extends Record<infer K2, infer V2>
? K extends K2
? V extends V2
? undefined
: never
: never
: never

代码现在变成

type Foo = string & { _fooBrand: undefined }
type T = Record<Foo, string>
const f = (a: T, b: Foo) => {
const c = get(a, b) // 👈
set(a, b, 'asdf')
}

最新更新