我有这个:
type Two = {
one: number,
two: string,
three: boolean
}
我希望它创建一个看起来像这样的类型:
type RenamedTwo = {
one: number,
two: string,
four: boolean // difference
}
我试着用这种方式来创造它:
type Rename<T, K extends keyof T, N> = Pick<T, Exclude<keyof T, K>> & { [N]: T[K] }
尝试使用这种方式:
type Renamed = Rename<Two, 'three', 'four'>
但是TSlint将[N]
标记为错误并给出以下错误消息:
[ts]类型文本中的计算属性名称必须引用其类型为文本类型或“唯一符号”类型的表达式。[ts] 'N'仅引用类型,但在此处用作值。
3条答案
按热度按时间w6mmgewl1#
您还需要为重命名的属性使用Map类型:
请注意,如果您提供更多属性,则这将无法按预期工作:
5w9g7ksd2#
在当前的typescript版本4.6.2中,有一个重Map语法可供使用。它可以更容易地实现这一点。
PlayGround
RenameByT
类型可以分为几个部分。下面的例子是renameOne
K in keyof U
表示U
中的所有密钥。例如one | two | three
as
子句,因为ts4.1可以使用。4.4.4不能用,4.6.2可以用。用于根据条件类型重命名KeyK
K extends keyof T
. keyof T表示three | five
。T[K] extends string
表示T[K]
是字符串。T['three']
是字符串,所以返回four
,T['five']
返回nouse
;1.返回类型
K extends keyof U
,所以T['three']
被满足,所以返回{ four: U['three'] }
意味着{ four: boolean}
1.其他键作为原点返回
参考文献:
https://github.com/microsoft/TypeScript/issues/40833https://www.typescriptlang.org/docs/handbook/2/mapped-types.html
6jjcrrmo3#
也许值得一提的是,您可以解决OP的原始问题,而无需编写像
Rename
这样的泛型类型。如果你只想做一次,你可以做一些更简单的事情。