【问题标题】:Enforcing a certain value using Type definition of Typescript使用 Typescript 的类型定义强制执行某个值
【发布时间】:2019-08-07 23:48:50
【问题描述】:

我有一个Car 类,它定义了汽车的model 的属性。

只有 3 种可能的模型:“ModelT”、“ModelQ”和“ModelX”。所以我决定定义一个模型类型,例如:

type Model = 'ModelT' | 'ModelQ' | 'ModelX';

和 Car 构造方法为

class Car {
  constructor(model: Model) {
    this.model = model;
  }
}

还有一个远程服务可以返回我应该购买的汽车类型。如果我使用这样的服务,我的代码看起来像

const model = getModelFromRemoteService();
const car = new Car(model);

强制执行逻辑以检查在运行时远程服务返回的模型实际上是type Model 定义中指定的模型之一的最佳方法是什么?

【问题讨论】:

标签: typescript typescript-types


【解决方案1】:

不可能从类型/接口开始并从中获取运行时行为。 TypeScript 中的类型系统仅在您编写程序时存在。它是在运行时执行的发出的 JavaScript 中的completely erased

幸运的是,您可以做相反的事情:从运行时存在的对象开始,然后让 TypeScript 编译器为其推断出类似的类型。在您的情况下,我建议从您要检查的值数组开始,然后按照here 所述进行操作:

// helper function needed before TS3.4 to get a tuple of string literals
// instead of just string[]
const stringTuple = <T extends string[]>(...args: T) => args;

const models = stringTuple('ModelT', 'ModelQ', 'ModelX');
// inferred type of models is ['ModelT', 'ModelQ', 'ModelX'];

// in TS3.4+, const models = ['ModelT', 'ModelQ', 'ModelX'] as const;

type Model = typeof models[number];
// inferred type of Model is 'ModelT' | 'ModelQ' | 'ModelX'

现在您再次输入了 Model,并且您还拥有了可用于为其创建 type guardmodels 数组值:

function isModel(x: any): x is Model {
  return models.indexOf(x) >= 0;
  // or return models.includes(x) for ES2016+
}

现在你可以像这样使用它了:

class Car {
  model: Model;
  constructor(model: Model) {
    this.model = model;
  }
}
// assume this returns a string
declare function getModelFromRemoteService(): string;

// wrap getModelFromRemoteService so that it returns a Model 
// or throws a runtime error
function ensureModelFromRemoteService(): Model {
  const model = getModelFromRemoteService();
  if (isModel(model)) return model;
  throw new Error("THAT REMOTE SERVICE LIED TO ME");
}


const model = ensureModelFromRemoteService();
const car = new Car(model); // works now

好的,希望对您有所帮助。祝你好运!

【讨论】:

    猜你喜欢
    • 2021-06-30
    • 2020-06-10
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-12
    • 2023-01-18
    • 1970-01-01
    相关资源
    最近更新 更多