如何捕获嵌套 属性 的类型参数并将其映射到其他对象
How to capture type argument of nested property and map it to something else
我真的不知道怎么问这个问题,所以我认为最好的方法是举例说明我正在尝试做的事情。假设我有以下对象:
const obj = {
one: 'some string',
two: new Set<string>(),
};
现在我想编写一个函数,接收该对象并将 Set
转换为相同类型的 Array
。
这是未类型化的 javascript 实现:
const obj = {
one: 'some string',
two: new Set().add('one').add('two'),
};
function convertToArrays(objWithSets) {
return Object.entries(objWithSets).reduce((objectWithArrays, [key, value]) => {
if (value instanceof Set) {
objectWithArrays[key] = Array.from(value);
} else {
objectWithArrays[key] = value;
}
return objectWithArrays;
}, {});
}
console.log('converted', convertToArrays(obj));
如何正确输入上述函数? 澄清一下:它可以接受任何对象(不仅仅是一个,两个示例)并且如果它看到 Set<T>
,它将其转换为 Array<T>
.
我知道它需要捕获内部 Set
的类型(在本例中为 string
)并将该类型有条件地映射到 Array<string>
.
谢谢!
您可以混合使用映射类型和条件类型来执行此操作:
type InnerSetToArray<T> = {
[P in keyof T]:
T[P] extends Set<infer U>
? Array<U>
: T[P]
};
type InnerSet = { one: number, two: Set<string>, three: Set<Function>, four: Date };
// InnerArray === { one: number, two: string[], three: Function[], four: Date }
type InnerArray = InnerSetToArray<InnerSet>;
编辑:原创,下面过于具体的答案:
我们开始吧,基本上就像您描述的那样:
function convertToArrays<T extends { one: string, two: Set<any> }>(objWithSets: T):
T extends { one: string, two: Set<infer U> }
? { one: string, two: Array<U> }
: never {
/* ... */
}
// typeof x === { one: string, two: number[] }
const x = convertToArrays({ one: "hello", two: new Set([1, 2, 3]) })
我们允许它最初是 Set<any>
只是作为类型保护,然后根据条件推断实际类型。条件在匹配失败时缩小到 never
,这应该没问题,因为初始检查理论上保证条件将始终计算为真。
我真的不知道怎么问这个问题,所以我认为最好的方法是举例说明我正在尝试做的事情。假设我有以下对象:
const obj = {
one: 'some string',
two: new Set<string>(),
};
现在我想编写一个函数,接收该对象并将 Set
转换为相同类型的 Array
。
这是未类型化的 javascript 实现:
const obj = {
one: 'some string',
two: new Set().add('one').add('two'),
};
function convertToArrays(objWithSets) {
return Object.entries(objWithSets).reduce((objectWithArrays, [key, value]) => {
if (value instanceof Set) {
objectWithArrays[key] = Array.from(value);
} else {
objectWithArrays[key] = value;
}
return objectWithArrays;
}, {});
}
console.log('converted', convertToArrays(obj));
如何正确输入上述函数? 澄清一下:它可以接受任何对象(不仅仅是一个,两个示例)并且如果它看到 Set<T>
,它将其转换为 Array<T>
.
我知道它需要捕获内部 Set
的类型(在本例中为 string
)并将该类型有条件地映射到 Array<string>
.
谢谢!
您可以混合使用映射类型和条件类型来执行此操作:
type InnerSetToArray<T> = {
[P in keyof T]:
T[P] extends Set<infer U>
? Array<U>
: T[P]
};
type InnerSet = { one: number, two: Set<string>, three: Set<Function>, four: Date };
// InnerArray === { one: number, two: string[], three: Function[], four: Date }
type InnerArray = InnerSetToArray<InnerSet>;
编辑:原创,下面过于具体的答案:
我们开始吧,基本上就像您描述的那样:
function convertToArrays<T extends { one: string, two: Set<any> }>(objWithSets: T):
T extends { one: string, two: Set<infer U> }
? { one: string, two: Array<U> }
: never {
/* ... */
}
// typeof x === { one: string, two: number[] }
const x = convertToArrays({ one: "hello", two: new Set([1, 2, 3]) })
我们允许它最初是 Set<any>
只是作为类型保护,然后根据条件推断实际类型。条件在匹配失败时缩小到 never
,这应该没问题,因为初始检查理论上保证条件将始终计算为真。