简体   繁体   中英

Specialized function signatures in TypeScript

I am working with specialized function signatures in TypeScript. My understanding is that the following should work:

// Basic superclass and subclass
class Model { }
class Product extends Model { name: string; }

// Define interface for singleton factory class with generic create method.
interface IModels { create(type: any): Model; }

const ctors = {product: Product};

// Implement generic version of create.
class Models implements IModels {
  create(type: any): Model { return new ctors[type](); }
}

// Extend interface with specialized signature.
interface IModels { create(type: "product"): Product; }

const models = new Models;

const product: Product = models.create("product");

However, this yields the following error on the last line:

Class 'Models' incorrectly implements interface 'IModels'.
  Types of property 'create' are incompatible.
    Type '(type: any) => Model' is not assignable to type '{ (type: any): Model; (type: "product"): Product; }'.
      Type 'Model' is not assignable to type 'Product'.
        Property 'name' is missing in type 'Model'.

If I change the return type of create from Model to any , then it compiles, but why should I have to do that?

The interface...

interface IModels { create(type: "product"): Product; }

...is implemented in your Models class by the method signature...

create(type: any): Model;

...since any is an acceptable implementation of "product" . The compiler then only uses the method information from the Models class.

You can also get rid of your error by adding this information to your Models class as well in an overload signature:

class Models implements IModels {
    create(type: "product"): Product;
    create(type: any): Model;
    create(type: any): Model {
        return new ctors[type]();
    }
}

Update 2020

Nowadays, you would most likely write something along these lines:

const ctors = { product: Product };

class Models {
  create(type: keyof typeof ctors): Model {
    return new ctors[type]();
  }
}

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