使用 Typescript 的类型定义强制执行某个值
Enforcing a certain value using Type definition of Typescript
我有一个Car
class,它为车的model
定义了属性
只有 3 种可能的模型:'ModelT'、'ModelQ' 和 'ModelX'。所以我决定定义一个模型类型,例如:
type Model = 'ModelT' | 'ModelQ' | 'ModelX';
Car 构造方法为
class Car {
constructor(model: Model) {
this.model = model;
}
}
还有一个远程服务returns我应该买什么车。如果我使用这样的服务,我的代码看起来像
const model = getModelFromRemoteService();
const car = new Car(model);
执行逻辑以检查 在运行时 远程服务返回的模型实际上是 type Model
定义中指定的模型之一的最佳方式?
无法从 type/interface 开始并从中获取运行时行为。 TypeScript 中的类型系统仅在您编写程序时存在。它是在运行时执行的发出的 JavaScript 中的 completely erased。
幸运的是,您可以做相反的事情:从运行时存在的对象开始,让 TypeScript 编译器为它推断一个类似的类型。在你的情况下,我建议从你要检查的值数组开始,然后按照 :
所述进行
// 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
类型又回来了,您还有 models
数组值,可用于为其创建 type guard:
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
好的,希望对您有所帮助。祝你好运!
我有一个Car
class,它为车的model
定义了属性
只有 3 种可能的模型:'ModelT'、'ModelQ' 和 'ModelX'。所以我决定定义一个模型类型,例如:
type Model = 'ModelT' | 'ModelQ' | 'ModelX';
Car 构造方法为
class Car {
constructor(model: Model) {
this.model = model;
}
}
还有一个远程服务returns我应该买什么车。如果我使用这样的服务,我的代码看起来像
const model = getModelFromRemoteService();
const car = new Car(model);
执行逻辑以检查 在运行时 远程服务返回的模型实际上是 type Model
定义中指定的模型之一的最佳方式?
无法从 type/interface 开始并从中获取运行时行为。 TypeScript 中的类型系统仅在您编写程序时存在。它是在运行时执行的发出的 JavaScript 中的 completely erased。
幸运的是,您可以做相反的事情:从运行时存在的对象开始,让 TypeScript 编译器为它推断一个类似的类型。在你的情况下,我建议从你要检查的值数组开始,然后按照
// 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
类型又回来了,您还有 models
数组值,可用于为其创建 type guard:
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
好的,希望对您有所帮助。祝你好运!