typescript - 具有泛型的打字稿初始化对象
问题描述
我想要的是这样的:
class ThemeExample <T> {
static theme : T;
static init(theme : T){
ThemeExample.theme = theme;
}
};
//config it
ThemeExample.init({
hello : 'hi'
})
//in another file access properties with auto completion
ThemeExample.theme.hello
但这不起作用。TS2302: Static members cannot reference class type parameters.
尝试了其他一些事情,例如在函数中创建类并返回它,并在类中使用泛型函数。仍然找不到让我初始化此配置一次的方法。然后稍后访问主题并自动完成其他文件中的所有属性。我需要这样的东西请帮助我,我太沮丧了。
解决方案
a 的静态部分class
由类构造函数组成,并且只有一个这样的构造函数。它无法访问实例类型上的任何泛型参数,因为类构造函数需要能够为该泛型参数的任何可能规范创建实例。在您的ThemeExample<T>
代码中,类构造函数必须能够创建ThemeExample<string>
和的实例ThemeExample<number>
。如果您可以拥有 type 的静态属性T
,则意味着它必须同时是 astring
和 anumber
以及任何其他可能的类型T
。它不起作用。
从概念上讲,您可以想象ThemeExample
有一个static
名为theme
type的属性unknown
,然后当您调用时ThemeExample.init("hello")
,编译器会缩小类构造函数的范围,ThemeExample
以便theme
现在它是 typestring
而不是unknown
. 但是没有很好的机制来做到这一点。您可以想象编写类似断言函数的东西会产生这样的效果:
interface ThemeExampleConstructor<T = unknown> {
theme: T;
init<T>(theme: T): asserts this is ThemeExampleConstructor<T>;
new(): ThemeExample<T>;
}
declare const ThemeExample: ThemeExampleConstructor;
ThemeExample.theme.toUpperCase(); // error
ThemeExample.init("hello");
ThemeExample.theme.toUpperCase(); // okay
new ThemeExample().instanceProp.toUpperCase(); // okay
但是你不能用class
语法来做到这一点,即使你完成了这个,像这样的缩小也不能跨越文件边界甚至函数边界。没有任何机制可以让编译器在一个文件中看到在ThemeExample.init("hello")
另一个文件中发生之前ThemeExample.theme.toUpperCase()
。所以我们根本不能这样做。
相反,我建议采用产生新类构造函数的工厂函数的路线。该函数将存在于某个库中,例如Library/index.ts
:
export function initThemeExample<T>(theme: T) {
return class ThemeExample {
static theme = theme;
};
}
然后在另一个文件(如userLib.ts
)中,用户可以import
从库中配置并重新导出:
import {initThemeExample} from './Library'
//config it
export const ThemeExample = initThemeExample({
hello: 'hi'
})
然后用户可以在所有其他文件中使用这个配置的构造函数:
import {ThemeExample} from './userLib'
//import your ThemeExaple in another file
document.write(ThemeExample.theme.hello.toUpperCase()); // HI
推荐阅读
- swift - 如何快速编写 10 项的 Bessel 函数代码?
- python - 将元素动态添加到多维python列表
- python - 如何使用 pandas.read_csv( ) 读取原来的行名?
- javascript - 从javascript中的函数结果中提取元素
- docker - 超线程会降低 Docker 的性能吗?
- python-3.x - 如何使用 python 和 powershell 将用户添加到 Windows 10
- javascript - 将 id 添加到孩子并将它们存储为数组以列出
- c# - For循环在模型视图ASP.NET MVC C#
- javascript - 如何将 v-bind 的值更新为 prop?
- javascript - 每次组件重新渲染时,如何在 useEffect 中触发加载事件侦听器?