typescript - 基于输入枚举的Typescript条件返回接口
问题描述
要求是提供一个枚举数组作为参数来定义返回类型接口。基于这些枚举属性Key.A
和/或Key.B
返回类型接口应该包含A1
和或B1
带有属性键(如枚举键)A
和或B
。
预设置如下所示:
import { parse } from 'someWhere'; \\ will capitalize config first-lvl attributes
enum Key {
A = "a",
B = "b",
}
interface A1 {
x: string;
}
interface B1 {
y: string;
}
type FF = {
A: A1;
B: B1;
};
type Conf = <???>???;
const Fn = <E extends Key>(key: E[], config: unknown): Conf<E> => {
return parse.JSON(key, config) as Conf<E>;
};
结果应该Fn
是使用一些枚举值调用并且返回的接口仅包含相应的属性,例如:
const config = '{ "b": { "y": "some string" } }';
const res = Fn([Key.B], config);
console.log(res.B.y) // 'some string'
console.log(res.A.x) // Type Error: Property 'A' does not exist on type
基于此,我尝试了以下方法:
type Conf<E extends Key> = {
[K in keyof typeof Key]: K extends E[keyof E] ? FF[K] : never;
};
const res = Fn([Key.B]);
通过此实现, Key 的所有属性都存在于res
:
第二种方法是将 Conf 定义为
type Conf<E extends Key> = {
[K in E]: K extends E[keyof E] ? FF : never;
};
返回接口中仅存在属性b
,但我无法找到如何索引FF
以基于 enum => 选择正确的接口B1
。此外,生成的界面res.b.
不是res.B.
解决方案
这真的很棘手Key.B
,因为"B"
和"b"
都是不同的。
如果您愿意重写您的映射FF
,使其以实际枚举值而不是枚举属性名称为键"a"
,"b"
那么它变得非常简单。您可以只使用Pick<FF, E>
来获取返回类型。
type FF = {
a: A1;
b: B1;
};
const fn = <E extends Key>(key: E[], config?: unknown): Pick<FF, E> => {
return parse.JSON(key, config) as Pick<FF, E>;
};
const res1: {b: B1} = fn([Key.B]);
const res2: {a: A1} = fn([Key.A]);
const res3: {a: A1, b: B1} = fn([Key.A, Key.B]);
否则我也无法完全理解它。
推荐阅读
- php - 从 raspbian 上的 PHP 脚本更改静态 IP 地址
- sql - 与 SQL Server 中的 Excel Rate() 函数类似的功能
- ruby-on-rails - 需要从拥有数百万条记录的数据库中将数据导出为 CSV。还需要覆盖Rails中的行
- android-studio - ^map 在 Android Studio 4.0 中是什么意思?
- linux - 在多个文件对象上使用 gcc
- python-3.x - TypeError:buy_sell() 采用位置参数,但给出了 1
- sql - 如何按插入顺序选择记录,然后按类型分组
- google-cloud-platform - 当 num-nodes 设置为 2 时,GCP Kubernetes 创建了 6 个节点
- python - PonyORM:没有为实体“用户”生成映射
- python-3.x - Python3:通过捕获的异常调用递归函数后,Try 块不会停止循环