在对象内将一种 TypeScript 类型与另一种类型交换
Swap one TypeScript type with another inside an object
我有以下类型:
type Target = number | undefined;
type MyObject = {
some: string;
properties: string;
id: Target;
}
我想想出一个通用的方法来用 number
替换 Target
,比如:
type MyObjectTransformed = TargetToNumber<MyObject>;
/**
* MyObjectTransformed is now:
*
* {
* some: string;
* properties: string;
* id: number;
* }
*/
如果您知道 Target
总是在 id
字段中,就很容易了,我不需要这方面的帮助。
但是如果 Target
可以在任何地方呢?像这样也应该有效:
TargetToNumber<{
some: string;
other: Target;
properties: string;
}>
更糟糕的是...它在嵌套时也需要工作!像这样应该仍然用 number
:
替换 Target
TargetToNumber<{
some: string;
properties: string;
nested: {
arbitrarily: {
deep: Target;
};
};
}>
如果你好奇我为什么要做这么奇怪的事情,this is why I'm asking。
使用条件类型:如果任意类型 T
是 A
或 A
的子类型,我们将其替换为 B
,否则如果它是一个对象type 我们递归映射属性,否则我们将类型保留为 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]
来测试它们是同一类型。
我有以下类型:
type Target = number | undefined;
type MyObject = {
some: string;
properties: string;
id: Target;
}
我想想出一个通用的方法来用 number
替换 Target
,比如:
type MyObjectTransformed = TargetToNumber<MyObject>;
/**
* MyObjectTransformed is now:
*
* {
* some: string;
* properties: string;
* id: number;
* }
*/
如果您知道 Target
总是在 id
字段中,就很容易了,我不需要这方面的帮助。
但是如果 Target
可以在任何地方呢?像这样也应该有效:
TargetToNumber<{
some: string;
other: Target;
properties: string;
}>
更糟糕的是...它在嵌套时也需要工作!像这样应该仍然用 number
:
Target
TargetToNumber<{
some: string;
properties: string;
nested: {
arbitrarily: {
deep: Target;
};
};
}>
如果你好奇我为什么要做这么奇怪的事情,this is why I'm asking。
使用条件类型:如果任意类型 T
是 A
或 A
的子类型,我们将其替换为 B
,否则如果它是一个对象type 我们递归映射属性,否则我们将类型保留为 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]
来测试它们是同一类型。