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.