我不确定这是否可能(或实际可行),但我很好奇.
我有一个包含string
个变量的强类型词典,如下所示:
const variables: Variables = {
REACT_APP_MY_VARIABLE: 'Test',
REACT_APP_MY_BOOLEAN_VARIABLE: 'true'
};
我直接通过variables
对象访问这些变量:const myVariable = variables.REACT_APP_MY_VARIABLE;
等.
"问题"是,对于这些值中的一些值,string
不是值的合理表示(例如'true'
),所以在使用它之前,我必须以某种方式转换它.
const myBoolean = toBoolean(variables.REACT_APP_MY_BOOLEAN_VARIABLE);
这基本上没问题...但是,如果可以将转换后的值存储在一个对象中,以及在未指定转换的情况下默认存储为字符串的所有其他值,那就太好了.
我曾想过创建一种包装类来存储原始字符串,然后让一些getter来执行转换,但我希望能够自动执行这一操作,而不是 for each 值都详尽地创建getter.
class EnvironmentVariables {
// This should actually be a private variable but my keyboard
// doesn't have a hash key.
private _variables: Variables;
constructor(variables: Variables) {
this._variables = variables;
}
get myBooleanVariable() {
return toBoolean(this._variables.REACT_APP_MY_BOOLEAN_VARIABLE);
}
}
现在我可以很好地获得布尔值:
const environmentVariables = new EnvironmentVariables(variables);
// myBoolean = true
const myBoolean = environmentVariables.myBooleanVariable;
但是,如果我想要其他值,我必须 for each 值都创建一个getter,当最常见的情况只是返回string
值时,这是相当困难的:
// I don't want to make one of these for every value.
get myVariable() {
return this._variables.REACT_APP_MY_VARIABLE;
}
为此,我可以以编程方式为任何值添加"默认"获取方法,而不需要显式覆盖,并且只需将其映射到内部_variables
集合.
constructor(variables: Variables) {
this._variables = variables;
for (const key in variables) {
const getterName = key.replace('REACT_APP_', '').toCamelCase();
if (this.hasOwnProperty(getterName)) {
continue;
}
Object.defineProperty(this, getterName, {
get: () => this._variables[key];
});
}
}
这真是太棒了!除了我想不出如何让TypeScrip识别出当我将一个值加到variables
时,该值应该也可以通过EnvironmentVariables
访问.
const environmentVariables = new EnvironmentVariables(variables);
// myBooleanVariable = true, I am happy.
const myBooleanVariable = environmentVariables.myBooleanVariable;
// myVariable = 'Test'... but TypeScript gives an error saying there's
// no 'myVariable' on type 'EnvironmentVariables'.
const myVariable = environmentVariables.myVariable;
理想情况下,我也非常希望它能够将变量名变为驼峰大小写,并删除‘REACTION_APP’前缀,因为它非常笨重.我怀疑这是否可能,但我认为这可能是模板类型和泛型可以完成的事情?
基本上,我想要的东西是这样工作的:
const variables = {
REACT_APP_MY_VARIABLE: 'Test',
REACT_APP_MY_BOOLEAN_VARIABLE: 'true'
};
class EnvironmentVariables {
... // Magic goes here.
get myBooleanVariable() {
return toBoolean(this._variables.REACT_APP_MY_BOOLEAN_VARIABLE);
}
}
const environmentVariables = new EnvironmentVariables(variables);
// TypeScript allows this even though there's no getter defined in
// EnvironmentVariables, and it recognises that the value is a `string`.
const myVariable = environmentVariables.myVariable;
// There's a getter defined for myBooleanVariable, so TypeScript
// recognises that it is a boolean.
const myBooleanVariable = environmentVariables.myBooleanVariable;
所以...这是可能的吗,还是我只是在浪费时间?