在属性(键)上使用匹配的 TypeScript 接口

问题描述 投票:0回答:1

我想我想做一些不寻常的事情。我有以下代码:

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
1个回答
0
投票

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';
}

Playground 代码链接

© www.soinside.com 2019 - 2024. All rights reserved.