Convert base class instance to derived class without typecasting in typescript
P粉451614834
P粉451614834 2024-02-25 19:48:09
0
2
438

I extended a new class from the base class and added some properties. How to create an instance of a derived class using a given base class (including attached properties)?

This code works, but it casts the class type and is not type safe

How to do this without type conversion?

// Base class is imported from a package. Not editable
class BaseClass {
  public x: number;
  public power() {
    return this.x * 2;
  }
}

export interface CustomClass extends BaseClass {
  value: number;
}

function createCustomClass(base: BaseClass, myValue: number): CustomClass {

  // it's not type safe to cast this variable
  // How to do it the right way in Typescript?
  const result: CustomClass = base as CustomClass;
  result.value = myValue;
  return result;
}

P粉451614834
P粉451614834

reply all(2)
P粉765570115

I don't think it's possible to rule out type conversion completely with your approach, but if you use type Guard to check if the variable result is valid CustomClass (in mine The implementation is isCustomClass ), that would be safe: p>

// Base class is imported from a package. Not editable
class BaseClass {
  public x: number;
  public power() {
    return this.x * 2;
  }
}

export interface CustomClass extends BaseClass {
  value: number;
}

function isCustomClass(classToCheck: any): classToCheck is CustomClass {
  return (
    typeof classToCheck?.value === "number" && classToCheck instanceof BaseClass
  );
}

function createCustomClass(base: BaseClass, myValue: number): CustomClass {
  const result = base;
  (result as CustomClass).value = myValue;
  if (!isCustomClass(result)) {
    throw new Error("Cannot create valid `CustomClass`");
  }

  return result;
}
P粉486138196

You can use the Object.assign () method to add properties to the target object. This method returns the target object, and its call signature in the TypeScript library that is the intersection of the input types.

This means your createCustomClass() can be implemented like this:

function createCustomClass(base: BaseClass, myValue: number): CustomClass {
  return Object.assign(base, { value: myValue });
}

The return type is BaseClass & {value: number}, and its structure is the same as CustomClass, so there will be no errors in function compilation, and there is no type assertion required.

Playground code link p>

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template