typescript - 在对象内将一种 TypeScript 类型与另一种类型交换
问题描述
我有以下类型:
type Target = number | undefined;
type MyObject = {
some: string;
properties: string;
id: Target;
}
我想提出一种通用的方法来替换Target
,number
例如:
type MyObjectTransformed = TargetToNumber<MyObject>;
/**
* MyObjectTransformed is now:
*
* {
* some: string;
* properties: string;
* id: number;
* }
*/
如果您知道Target
总是在id
现场,这很容易,我不需要帮助。
但如果Target
可以在任何地方呢?像这样也应该有效:
TargetToNumber<{
some: string;
other: Target;
properties: string;
}>
更糟糕的是......它也需要在嵌套时工作!像这样仍应替换Target
为number
:
TargetToNumber<{
some: string;
properties: string;
nested: {
arbitrarily: {
deep: Target;
};
};
}>
如果你好奇我为什么要做这么奇怪的事情,这就是我问的原因。
解决方案
使用条件类型:如果任意类型T
是A
或 的子类型A
,我们将其替换为B
,否则如果它是对象类型,我们递归映射属性,否则我们将类型保留为T
。
type TargetToNumber<T> = SubstituteType<T, Target, number>;
type SubstituteType<T, A, B> =
T extends A
? B
: T extends {}
? { [K in keyof T]: SubstituteType<T[K], A, B> }
: T;
如果您只想完全替换A
并单独保留子类型A
(例如never
,始终是子类型...),您可以替换T extends A
为[A, T] extends [T, A]
以测试它们是否为相同类型。
推荐阅读
- pytorch - 向预训练模型添加参数
- swift - 在 ubuntu 上使用 MongoSwift 时,Vapor 崩溃
- c# - 从控制台应用程序运行 WPF 应用程序时,App.xaml 被忽略
- .net - 无法突出显示组合框中的文本
- webpack - 如何从构建中删除 Webpack 代码?
- angular - 添加新项目时更新列表
- javascript - 为什么元素上的 load()、on()、bind() 等不可用
- python-3.x - 在 s3 中读取镶木地板文件时,Dask 数据帧抛出错误
- haskell - 为什么 Haskell 不允许更复杂的中缀表达式?
- javascript - setInterval() 不适用于制作数字时钟