typescript - 具有动态静态字段的函数
问题描述
我需要使用泛型类型的动态静态字段为函数编写一个类型
interface WithStatic<P, T extends string[]> {
(props: P): void;
[K in T]: WithStatic<P, T>; // TS Error: A computed property name must be of type 'string', 'number', 'symbol', or 'any'.
}
如果我将动态字段移得更深(将其放到另一个字段中),则一切正常:
interface WithStatic<P, T extends string> {
(props: P): void;
options: {
[K in T]: WithStatic<P, T>;
};
}
示例用法:
const withStatic = (props => {}) as WithStatic<{}, 'maybe' | 'ready'>;
然后输入
withStatic.options.
显示maybe
和ready
:
如何改为在接口的根级别定义动态类型?
编辑
解决方案
映射类型不能包含除映射表达式(即[K in T]: ...
)之外的任何其他声明。它也不能出现在界面中。
考虑到这一点,您将需要在类型别名中使用交集来描述您想要的类型。这将起作用:
type WithStatic<P, T extends string[]> = {
(props: P): void;
} & {
[K in T[number]]: WithStatic<P, T>;
}
let c = ((p: {}) => 1) as any as WithStatic<{}, ['maybe', 'ready']>
c.maybe.maybe // not sure this is what you are going for here but it compiles..
虽然上面的类型有效,但我不确定它是否真的有意义,也许您希望声明的字段T
是特定类型(例如string
orany
或boolean
),那么您可以只使用映射类型Record
。此外,我们通常将多个键作为联合而不是元组传递:
type WithStatic<P, T extends string> = {
(props: P): void;
} & Record<T, string> // replace strign with whatever
let c = ((p: {}) => 1) as any as WithStatic<{}, 'maybe' | 'ready'>
c.maybe = ""
编辑
关于评论,您可以允许c.maybe.ready
但不允许,c.maybe.maybe
但您将需要使用联合而不是元组:
type WithStatic<P, T extends string> = {
(props: P): void;
} & {
[K in T]: Exclude<T, K> extends never? string : WithStatic<P, Exclude<T, K>>; // Added bottom
}
let c = ((p: {}) => 1) as any as WithStatic<{}, 'maybe' | 'ready'>
c.maybe.maybe // error
c.ready.maybe = ""
c.maybe.ready = ""
推荐阅读
- android-studio - 如何删除 Flutter 中默认的白色启动画面。我根本不想要启动画面
- android - Unity 2019 - 无法启用 MultiDex 支持
- google-cloud-platform - 如何使用 terraform 和谷歌云将主机重定向从辅助域添加到主域
- pandas - 如果没有完全匹配的值,则使用条件为新的 df 列分配值并使用更大的值
- html - 由于文件大,无法推送到 github
- flutter - 当仅打开另一个应用程序时,如何阻止视频在后台播放?
- python - 无法使用带有python的beautifulsoup从网页中提取文本
- java - 如何解决 Spring Security 中的 DefaultSecurityFilterChain?
- javascript - 如何在此弹出代码中添加网站链接?
- javascript - 如何创建一个单元格不可点击的表格