我想我想做一些不寻常的事情。我有以下代码:
import { writeFileSync } from 'fs';
import path from 'path';
interface VariablesType {
myVar: string;
[key: string]: string | number;
}
export class Variables {
static async load(): Promise<VariablesType> {
return (await import('variables.json')).default;
}
static save(variables: VariablesType): void {
const prettyJson = JSON.stringify(variables, null, 2);
writeFileSync(
`${path.join(__dirname, `variables.json`)}`,
prettyJson,
);
}
}
在我的代码中,我需要能够执行以下操作:
const variables = await Variables.load();
variables[`myVar${someStringDeterminedAtRuntime}`] = 'some string';
有什么方法可以在界面中解释这一点吗?例如(知道这是完全错误的):
interface VariablesType {
/myVar.*/: string;
[key: string]: string | number;
}
我想要这个的原因是,当我进行动态导入时,我希望为
myVar<whatever>
分配正确的 string
类型。
我承认我可能从错误的角度来处理这个问题,也许有更好的方法来做到这一点。任何帮助将不胜感激。
TypeScript 中没有正则表达式验证的字符串类型。所以
/myVar.*/
不能直接这样表达。在 microsoft/TypeScript#41160 上有针对此类类型的开放功能请求,无论其价值如何。
幸运的是,以指定前缀开头的字符串的特定模式可以使用带有string
占位符的
模板文字类型来表示,如microsoft/TypeScript#40598:中实现
type StartsWithMyVar = `myVar${string}`;
let str: StartsWithMyVar;
str = "myVarHello" // okay
str = "myVarGoodbye" // okay
str = "Greetings" // error!
此外,您可以使用占位符模板文字类型作为索引签名中的键:
interface VariablesType {
[key: StartsWithMyVar]: string;
[key: string]: string | number;
}
因此
VariablesType
意味着具有 string
值键的每个属性都必须是 string | number
类型,特别是,每个以 "myVar"
开头的属性必须是 string
类型:
const variables: VariablesType = {};
variables.myVarHello = "x"; // okay
variables.myVarGoodbye = 123; // error
variables.Greetings = 123; // okay
现在您的代码示例已按编写方式编译:
function foo(someStringDeterminedAtRuntime: string) {
variables[`myVar${someStringDeterminedAtRuntime}`] = 'some string';
}