我不想在这里重复keyof T
表达式:
// This type is meant to achieve something like ReturnType<typeof Object.entries>
type ObjectEntries<T extends object> = [keyof T, T[keyof T]][];
所以我这样做了,但它不起作用:
type ObjectEntries<T extends object, U = keyof T> = [U, T[U]][];
// Type 'U' cannot be used to index type 'T'
然而,如果U
扩展到keyof T
,它是有效的,但为什么?
type ObjectEntries<T extends object, U extends keyof T = keyof T> = [U, T[U]][];
U extends X
表示U
需要是扩展X
的类型,也称为类型约束。如果这样,则必须指定U
,如果在实例化ObjectEntries
时不指定,则会出现编译器错误。
U = X
意味着,如果在实例化ObjectEntries
时未指定U
,则默认情况下它将是X
,但由于U
没有任何约束,因此U
可以是任何类型(例如string
(。
约束和默认值有不同的用途,因此,如果希望U
默认为keyof T
,从而不必指定它,则需要= keyof T
;如果还希望约束U
,从而只能指定属于keyof T
子类型的类型,则需要使用extends keyof T
。该约束为TyepScript提供了足够的信息,使其知道用U
索引T
是安全的,因为U
的任何指定类型都必须是keyof T
的子类型