简体   繁体   中英

Type check between class and object literal in TypeScript

in TypeScript, an object literal can be assigned to a class typed variable if that object provides all properties and methods that the class needs.

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;

What I want to do here is to prevent this kind of assignment based on two reasons:

  1. instance instanceof MyClass should be true;
  2. I can assign an object with more properties (see above).

In this way, TypeScript class works more like an interface. Is there a way I can prevent this?

I don't know if I understood your question correctly but what I infer from your code is that.

In your second assignment, the variable literal is not defined as the type MyClass

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

So, you are just trying to create a const variable with some values.

From the TypeScript docs , what you're observing seems to be the expected behavior:

Type compatibility in TypeScript is based on structural subtyping. Structural typing is a way of relating types based solely on their members.

So if two types have the same structure, it's intended that objects of those types can be assigned to each other.

Workaround: private members

Once you start adding private members to a class (which you'd almost always do in practice), the type checking works much closer to how you want.

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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM