[英]Typescript init object with generic
What I want is something like this:我想要的是这样的:
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
But this doesn't work.但这不起作用。
TS2302: Static members cannot reference class type parameters.
Tried a few other things such as making the class in a function and return it, and use functions generic in the class.尝试了其他一些方法,例如在 function 中制作 class 并返回它,并使用 class 中的通用函数。 Still couldn't find a way that would let me initialize this config once.
仍然找不到让我初始化此配置一次的方法。 And then access the theme later and get auto completion for all its properties in other files.
然后稍后访问主题并自动完成其他文件中的所有属性。 I need something like this please help me, I'm too frustrated.
我需要这样的东西请帮助我,我太沮丧了。
The static side of a class
consists of the class constructor, and there is exactly one such constructor. class 的
class
端由 class 构造函数组成,并且只有一个这样的构造函数。 It has no access to any generic parameters on the instance type, because a class constructor needs to be able to create instances for any possible specification of that generic parameter.它无法访问实例类型上的任何泛型参数,因为 class 构造函数需要能够为该泛型参数的任何可能规范创建实例。 In your
ThemeExample<T>
code, the class constructor must be able to make instances of, say, ThemeExample<string>
and ThemeExample<number>
.在您的
ThemeExample<T>
代码中,class 构造函数必须能够创建ThemeExample<string>
和ThemeExample<number>
的实例。 If you could have a static property of type T
, it would mean that it would have to be both a string
and a number
and any other possible type for T
.如果您可以拥有
T
类型的 static 属性,则意味着它必须是string
和number
以及T
的任何其他可能类型。 It doesn't work.它不起作用。
Conceptually you could imagine ThemeExample
as having a static
property named theme
of type unknown
, and then when you call ThemeExample.init("hello")
, the compiler would narrow the ThemeExample
class constructor so that theme
is now of type string
instead of unknown
.从概念上讲,您可以将
ThemeExample
想象为具有名为theme
类型为unknown
的static
属性,然后当您调用ThemeExample.init("hello")
时,编译器将 缩小ThemeExample
class 构造函数的范围,以便theme
现在是string
类型而不是unknown
类型。 But there is no good mechanism to do this.但是没有很好的机制来做到这一点。 You could imagine writing something like an assertion function which would have such an effect:
您可以想象编写类似断言 function的东西,它会产生这样的效果:
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
But you can't do it with class
syntax, and even if you got this done, narrowing like this doesn't work across file boundaries or even function boundaries.但是你不能用
class
语法来做到这一点,即使你完成了这个,像这样的缩小也不能跨越文件边界甚至 function 边界。 There's no mechanism whereby the compiler would see that ThemeExample.init("hello")
in one file happens before the ThemeExample.theme.toUpperCase()
in another file.没有任何机制可以让编译器看到一个文件中的
ThemeExample.init("hello")
发生在另一个文件中的ThemeExample.theme.toUpperCase()
之前。 So we can't do this at all.所以我们根本不能这样做。
Instead I'd suggest going the route of a factory function which produces new class constructors.相反,我建议走工厂 function 的路线,该工厂生产新的 class 构造函数。 This function would exist in some library, say
Library/index.ts
:这个 function 将存在于某些库中,例如
Library/index.ts
:
export function initThemeExample<T>(theme: T) {
return class ThemeExample {
static theme = theme;
};
}
Then in another file like userLib.ts
, a user could import
that from the library, configure, and re-export:然后在
userLib.ts
类的另一个文件中,用户可以从库中import
该文件,配置并重新导出:
import {initThemeExample} from './Library'
//config it
export const ThemeExample = initThemeExample({
hello: 'hi'
})
And then the user could use this configured constructor in all other files:然后用户可以在所有其他文件中使用这个配置的构造函数:
import {ThemeExample} from './userLib'
//import your ThemeExaple in another file
document.write(ThemeExample.theme.hello.toUpperCase()); // HI
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.