Search code examples
typescripttypescript-2.5

How do I convert or cast `{}` to `T` and preserve default values In TypeScript?


Say I have Product with three properties and their default values. How do I convert or cast {} to Product with respect to default value when there is no value in {}?

export class Product{
  Price:number=20;
  Label:string="No name";
  Details:string="no desc";
}
let laptop = {Label:'Laptop'} as Product;
//I would like to get this laptop ={Label:'Label',Price:20,Details:'no desc'}

Solution

  • This is not possible with type casting. All you're doing when you cast an object as Product is saying to the compiler, "This thing is a Product even though it doesn't have the same properties as a Product".

    If you want default values, you need to put a constructor on your class, like this:

    export class Product {
      price: number;
      label: string;
      details: string;
    
      constructor(obj: {price?: number, label?: string, details?: string}) {
        this.price = obj.price || 20;
        this.price = obj.label || "No name";
        this.details = obj.details || "No description";
      }
    }
    

    Then you can pass any partial configuration object and the other default values will get set.

    let laptop = new Product({label: 'Laptop'}); 
    // {label: 'Laptop', price: 20, details: 'No description'}
    

    Now, laptop will automatically be of type Product and you don't even have to cast it.

    Tip: you can use the Partial type to make typing your constructor parameter easier.

    type Partial<T> = {
      [P in keyof T]?: T[P];
    }
    

    Then your constructor parameter would look like constructor(obj: Partial<Product>)

    For more info on type assertions (aka type casting), read the 'Type Assertions' section of this article: https://www.typescriptlang.org/docs/handbook/basic-types.html.