【问题标题】:Type check between class and object literal in TypeScriptTypeScript 中的类和对象字面量之间的类型检查
【发布时间】:2019-07-05 19:45:48
【问题描述】:

在 TypeScript 中,如果该对象提供类所需的所有属性和方法,则可以将对象字面量分配给类类型变量。

class MyClass {
  a: number;
  b: string;
}

// Compiler won't complain
const instance: MyClass = { a: 1, b: '' };

// Compiler won't complain if I assign an object with more properties
const literal = { a: 1, b: '', c: false };
const instance2: MyClass = literal;

我在这里要做的是基于两个原因防止这种分配:

  1. instance instanceof MyClass 应该是真的;
  2. 我可以分配具有更多属性的对象(见上文)。

通过这种方式,TypeScript 类更像是一个接口。有什么办法可以防止这种情况发生吗?

【问题讨论】:

  • 基于问题的其余部分,我猜在第 2 点您的意思更像是“我不想允许分配具有更多属性的对象“?
  • @ecraig12345 是的,你完全正确!

标签: typescript


【解决方案1】:

来自the TypeScript docs,您所观察到的似乎是预期的行为:

TypeScript 中的类型兼容性基于结构子类型。结构类型是一种关联类型的方式仅基于它们的成员。

因此,如果两种类型具有相同的结构,则这些类型的对象可以相互分配。

解决方法:私有成员

一旦您开始向类添加私有成员(实际上您几乎总是这样做),类型检查的工作方式就更接近您想要的方式。

class MyClass {
  a: number;
  b: string;
  private c: number;
}

// "Property 'c' is missing in type '{ a: number; b: string; }' but required in type 'MyClass'."
const instance: MyClass = { a: 1, b: '' };

// "Property 'c' is private in type 'MyClass' but not in type '{ a: number; b: string; c: number; }'"
const literal: MyClass = { a: 1, b: '', c: 3 };

class OtherClass {
  a: number;
  b: string;
  private c: number;
}

// "Types have separate declarations of a private property 'c'"
const otherClass: MyClass = new OtherClass();

【讨论】:

  • 这篇文档正是我想看到的。谢谢。还有一个问题:如果我不想引入私有字段,那我就不能依赖instanceof了吧?
  • instanceof is is a plain JS operator,所以它会按照你想要的方式工作。
【解决方案2】:

我不知道我是否正确理解了您的问题,但我从您的代码中推断出的是。

在您的第二次分配中,变量 literal 未定义为类型 MyClass

const literal = { a: 1, b: '', c: false };

所以,你只是想用一些值创建一个 const 变量。

【讨论】:

  • 嗨。对不起,我忘记了一行代码,只是编辑了(见上文)。我想说的是,在“const literal: MyClass = {a: 1, b:'' ,c: false}”的情况下,编译器会抱怨 c 是未知的。但是上面的编译器不会抱怨,因此我将一个具有更多属性的对象分配给类类型变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-03
  • 2018-02-01
  • 2019-05-14
  • 2012-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多