首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于接口TypeScript的通用工厂

基于接口TypeScript的通用工厂
EN

Stack Overflow用户
提问于 2017-09-29 20:59:56
回答 4查看 2.8K关注 0票数 3

我想实现泛型方法,它将返回基于提供的接口的具体类型。这在TypeScript中是可能的吗?

下面是我的伪示例:

代码语言:javascript
复制
interface IDog {
  canRun: boolean;
}

interface IBird {
  canFly: boolean;
}

class Dog implements IDog {
  canRun: boolean;
}

class Bird implements IBird {
  canFly: boolean;
}

function createInstance<T>(): T {
  const key =  typeof T;

  switch (key) {
    case IBird:
      return new Bird();
     return 
      case IDog:
      return new Dog();
    default:
      break;
  }
}

// concrete is Dog
const concrete = createInstance<IDog>();

createInstance()方法是我试图实现的一个原始示例,它不会编译!

我想为createInstance()方法提供接口类型,并实现一些逻辑,为提供的接口创建具体类型。

在TypeScript中有可能吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-09-29 21:23:52

接口在运行时不可访问,但可以使用字符串文字类型添加类型检查。

代码语言:javascript
复制
interface IDog {
    canRun: boolean;
}

interface IBird {
    canFly: boolean;
}

class Dog implements IDog {
    canRun: boolean;
}

class Bird implements IBird {
    canFly: boolean;
}

function createInstance(type: 'bird'): Bird;
function createInstance(type: 'dog'): Dog;
function createInstance(type: string): any {
  switch (type) {
    case 'bird':
        return new Bird();
    case 'dog':
        return new Dog();
  }
}

// concrete is Dog
const concrete = createInstance('dog');

此外,我认为工厂返回类型应该是接口:

代码语言:javascript
复制
function createInstance(type: 'bird'): IBird;
function createInstance(type: 'dog'): IDog;

更新:

另一种方法是存储对类的引用:

代码语言:javascript
复制
interface IInterfaces {
    dog: IDog;
    bird: IBird;
}

type IFactory<T> = {
    [P in keyof T]: new() => T[P];
}

let factory: IFactory<IInterfaces> = {
    dog: Dog,
    bird: Bird
}

let dog = new factory.dog();
票数 4
EN

Stack Overflow用户

发布于 2017-09-29 21:22:04

您需要使用重载:

代码语言:javascript
复制
function createInstance(key: 'dog'): Dog;
function createInstance(key: 'bird'): Bird;
function createInstance(key: 'dog' | 'bird') {
  // implement
}

然后将键作为参数传递。

代码语言:javascript
复制
const dog = createInstance('dog'); // typeof dog is Dog
票数 2
EN

Stack Overflow用户

发布于 2017-09-29 21:15:16

当然,您可以在TypeScript中执行工厂方法。一种方法是:

代码语言:javascript
复制
interface IAnimal {

}

interface IDog extends IAnimal {
    canRun: boolean;
}

interface IBird extends IAnimal {
    canFly: boolean;
}

class Dog implements IDog {
    canRun: boolean;
}

class Bird implements IBird {
    canFly: boolean;
}

class AnimalFactory {
    public static create(animalType: string): IAnimal {
        switch(animalType) {
            case 'dog':
                return new Dog();
            case 'bird':
                return new Bird();
            default:
                throw new Error('Wrong animal type.');
        }
    }
}

const dog: IDog = AnimalFactory.create('dog');
const bird: IBird = AnimalFactory.create('bird');

注意,工厂隐藏实际的类名/实现,并通过接口进行操作。如果您愿意,还可以更进一步,并使用构建器模式返回与IAnimal接口兼容的动物,如

代码语言:javascript
复制
case 'dog':
    const dog: IDog = new DogBuilder()
        .setColor('white')
        .setWeight(30)
        .build() // whatever, you get the idea
    return dog;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46496840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档