打字稿:从通用类型中获取文字值
Typescript: Get the literal value from a generic type
是否可以从类型中获取文字值?例如:
const createRecord = <T>(type: T, data: number) => ({ type, data })
const r = createRecord<'TYPE_1'>('TYPE_1', 101)
// The type of `r` is { type: "TYPE_1"; data: number; }
不过我想省略第一个参数,直接写成:
const createRecord = <T>(data: number) => ({ type: typeof T, data })
const r = createRecord<'TYPE_1'>(101)
当然前面的例子是行不通的,因为typeof T
是一个类型,不是一个值。
你的函数createRecord
returns一个对象,一个对象是一个值,所以type
属性也必须有一个值,而不仅仅是一个类型。您可以做的是让 TypeScript 从您提供的值中推断出 T
的类型。如果您将泛型类型限制为 string
(或 number
等),TypeScript 只会推断文字类型。
您可以这样创建函数:
const createRecord2 = <T extends string>(type: T, data: number) => ({ type, data })
然后你做
const r2 = createRecord2('TYPE_1', 101)
r2.type // type is inferred as 'TYPE_1'
请注意,我没有在调用时指定 T
的类型,它是从给定的参数推导出来的。
看这里的区别:playground
正如Daniel在上一条消息中提到的,我们可以从参数中推断出泛型类型。问题在于该函数可能包含多个泛型类型,而 TypeScript 不允许省略其中的一些(但是您可以省略所有)。所以这里有一个解决问题的方法:
const createRecord = <S, T extends string>(type: T, data: S) => ({ type, data })
const r = createRecord('TYPE_1', 101)
// type of `r` is const r: { type: "TYPE_1"; data: number; }
请注意,泛型类型 T
和 S
是从参数 type
和 data
中推断出来的。但是你不能这样做:
const createRecord = <S, T extends string>(type: T, data: S) => ({ type, data })
const r = createRecord<number>('TYPE_1', 101)
// Expected 2 type arguments, but got 1.
还要注意 T
必须扩展字符串 才能获得字符串文字(否则,类型将只是 string
)。
是否可以从类型中获取文字值?例如:
const createRecord = <T>(type: T, data: number) => ({ type, data })
const r = createRecord<'TYPE_1'>('TYPE_1', 101)
// The type of `r` is { type: "TYPE_1"; data: number; }
不过我想省略第一个参数,直接写成:
const createRecord = <T>(data: number) => ({ type: typeof T, data })
const r = createRecord<'TYPE_1'>(101)
当然前面的例子是行不通的,因为typeof T
是一个类型,不是一个值。
你的函数createRecord
returns一个对象,一个对象是一个值,所以type
属性也必须有一个值,而不仅仅是一个类型。您可以做的是让 TypeScript 从您提供的值中推断出 T
的类型。如果您将泛型类型限制为 string
(或 number
等),TypeScript 只会推断文字类型。
您可以这样创建函数:
const createRecord2 = <T extends string>(type: T, data: number) => ({ type, data })
然后你做
const r2 = createRecord2('TYPE_1', 101)
r2.type // type is inferred as 'TYPE_1'
请注意,我没有在调用时指定 T
的类型,它是从给定的参数推导出来的。
看这里的区别:playground
正如Daniel在上一条消息中提到的,我们可以从参数中推断出泛型类型。问题在于该函数可能包含多个泛型类型,而 TypeScript 不允许省略其中的一些(但是您可以省略所有)。所以这里有一个解决问题的方法:
const createRecord = <S, T extends string>(type: T, data: S) => ({ type, data })
const r = createRecord('TYPE_1', 101)
// type of `r` is const r: { type: "TYPE_1"; data: number; }
请注意,泛型类型 T
和 S
是从参数 type
和 data
中推断出来的。但是你不能这样做:
const createRecord = <S, T extends string>(type: T, data: S) => ({ type, data })
const r = createRecord<number>('TYPE_1', 101)
// Expected 2 type arguments, but got 1.
还要注意 T
必须扩展字符串 才能获得字符串文字(否则,类型将只是 string
)。