Home > Net >  Disallow properties from derived class on assignment
Disallow properties from derived class on assignment

Time:01-26

Assume I have the following situation:

interface Base {
  a: string;
}

interface Derived extends Base {
  b: string;
}

const x: Derived = {
  a: "a",
  b: "b",
};

Is it possible to have the linter and/or compiler to complain about the following line:

const y : Base = x;

The purpose would be to discover that there are additional properties being assigned to y that do not exist in the Base class.

CodePudding user response:

How about this...

type A = {
    a: string;
};

type B = {
    b: string;
};

type Derived = A | B;

const x: Derived = {
    a: "a",
    b: "b",
};

const a: A = { a: "123" };
const b: B = { b: "234" };
const d: Derived = x;

const b1: B = x; // <---- Error
const a1: A = x; // <---- Error

Surely, with interface(s) alone, that won't be possible

CodePudding user response:

This comment is correct: TypeScript is structurally-typed.

This means that as long as you extend Derived from Base, then you cannot exclude Base's properties from Derived.

However, you can use structural typing to create an additional type which is compatible with Base and excludes the "excess" properties of Derived by typing them as optional properties of type never (via the help of some type utilites), like this:

TS Playground

interface Base {
  a: string;
}

interface Derived extends Base {
  b: string;
}

const x: Derived = {
  a: "a",
  b: "b",
};

type PreventExtendedProps<Base, Derived extends Base> = Base & Partial<Record<Exclude<keyof Derived, keyof Base>, never>>;

type BaseNotDerived = PreventExtendedProps<Base, Derived>;

// Inspect the type's properties:
declare const b: BaseNotDerived;
b.a // string
b.b // undefined

// Your example assignment:
const y: BaseNotDerived = x; /*
      ^
Type 'Derived' is not assignable to type 'BaseNotDerived'.
  Type 'Derived' is not assignable to type 'Partial<Record<"b", never>>'.
    Types of property 'b' are incompatible.
      Type 'string' is not assignable to type 'never'.(2322) */

  •  Tags:  
  • Related