问题描述
我从API调用中获得了一个json响应(以后将成为对象),我可以使用queryparams将其动态限制为某些字段。
我已经输入了完整的回复。
现在我要实现的是创建一个类型,该类型接受给定的字段并返回仅包含给定属性的对象类型。
我知道有些实用程序类型如Pick,但是它们不适用于嵌套对象。
示例:
interface ResponseInterface {
a: {
a: {
a: number;
b: string;
};
b: {
a: string;
b: boolean;
};
};
b: {
a: object | null;
b: string;
}[];
}
const filters = ['a.a.a','a.b.b','b.a']; //nested properties seperated by dots
const fakeFullResponse: ResponseInterface = { //calling the api without any filters
a: {
a: {
a: 123,b: 'aab',},b: {
a: 'aba',b: true,b: [
{
a: null,b: 'array bb',{
a: {},],};
interface ExpectedType { //after applying those filters to the object
a: {
a: {
a: number;
};
b: {
b: boolean;
};
};
b: {
a: null | object
}[];
}
const fakeFilteredResponse: ExpectedType = { //calling the api with those fields above would get me this
a: {
a: {
a: 123,b: {
b: true,};
是否有给定ExpectedType
接口和ResponseInterface
的动态创建filters
接口的方法?如果需要,可以更改filters
数组的格式,只要嵌套结构保持不变
解决方法
首先,ResponseInterface.b
的定义与ExpectedType.b
相比没有什么意义,因为前者是具有固定长度2的元组,而后者是任意长度的数组(更新:OP已解决此问题)。因此,让我假设您的意思是这样:
interface ResponseInterface {
a: {
a: {
a: number;
b: string;
};
b: {
a: string;
b: boolean;
};
};
b: {
a: null | object;
b: string;
}[];
}
接下来,如果过滤器是以字符串形式编写的,那么您将需要TypeScript来解析字符串文字类型,该功能仅在即将发布的4.1版中存在。即使具有这种功能,由于要逐个而不是按结构列出筛选器,因此重新排列类型结构要困难得多。
因此,我建议您改用一种类型的过滤器格式:
type filters = { 'a': { 'a': 'a','b': 'b' },'b': 'a' };
格式应该是不言自明的。然后,您可以使用以下实用程序:
type PickStructure<T,F> = F extends keyof T ? { [k in F]: T[k] } : {
[k in keyof F]: k extends keyof T ? (
T[k] extends (infer U)[] ? PickStructure<U,F[k]>[] : PickStructure<T[k],F[k]>
) : never;
};
type ExpectedType = PickStructure<ResponseInterface,filters>;
它有效。看到这个Playground Link