英文:
Is it possible to create a new interface, from an existing interface, with certain top level properties removed based on a condition?
问题
我有以下的接口:
interface Example {
'/api/good/path': {
get: Record<string, unknown>;
parameters: Record<string, unknown>;
};
'/api/alsogood/path': {
get: Record<string, unknown>;
};
'/api/bad/path': {
post: Record<string, unknown>;
};
'/api/technicallygood/path': {
get: Record<string, unknown>;
post: Record<string, unknown>;
};
}
是否可以从 Example 创建一个新的接口,但删除所有不包含 get 属性的嵌套对象?
我的目标是得到类似于以下的内容:
interface Example {
'/api/good/path': {
get: Record<string, unknown>;
parameters: Record<string, unknown>;
};
'/api/alsogood/path': {
get: Record<string, unknown>;
};
'/api/technicallygood/path': {
get: Record<string, unknown>;
post: Record<string, unknown>;
};
}
换句话说,因为 Example['/api/bad/path'] 不包含 get,所以它被移除了。所有其他的 Example 键保留,因为它们至少包含一个名为 get 的属性。
英文:
I have the following interface:
interface Example {
'/api/good/path': {
get: Record<string, unknown>;
parameters: Record<string, unknown>;
};
'/api/alsogood/path': {
get: Record<string, unknown>;
};
'/api/bad/path': {
post: Record<string, unknown>;
};
'/api/technicallygood/path': {
get: Record<string, unknown>;
post: Record<string, unknown>;
};
}
Is it possible to create a new interface from Example, but removing all the nested objects that don't contain a get property?
My goal is to end up with something like:
interface Example {
'/api/good/path': {
get: Record<string, unknown>;
parameters: Record<string, unknown>;
};
'/api/alsogood/path': {
get: Record<string, unknown>;
};
'/api/technicallygood/path': {
get: Record<string, unknown>;
post: Record<string, unknown>;
};
}
In other words, since Example['/api/bad/path'] did not contain a get, it was removed. All the other keys of Example remain, because they contain at least one property called get.
答案1
得分: 3
type RemoveBadEndpoints<T> = {
[K in keyof T as 'get' extends keyof T[K] ? K : never]: T[K];
};
解释:
我们遍历键,如果属性具有 'get' 属性,我们将 K 用作键,否则,never 将会移除此属性,因为 never 不能用作键并被视为空联合类型。
type GoodEndpoints = RemoveBadEndpoints<Example>;
英文:
This can be achieved by using mapped types and key remapping.
type RemoveBadEndpoints<T> = {
[K in keyof T as 'get' extends keyof T[K] ? K : never]: T[K];
};
Explanation:
We map through the keys, and if the property has the 'get' property, we use K as a key, otherwise, never will remove this property since never can't be used as a key and is considered as an empty union.
// type GoodEndpoints = {
// '/api/good/path': {
// get: Record<string, unknown>;
// parameters: Record<string, unknown>;
// };
// '/api/alsogood/path': {
// get: Record<string, unknown>;
// };
// '/api/technicallygood/path': {
// get: Record<string, unknown>;
// post: Record<string, unknown>;
// };
// }
type GoodEndpoints = RemoveBadEndpoints<Example>;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论