Typescript如何实现工厂模式

时间:2018-12-18 13:43:19

标签: typescript

我是打字机的新手,并尝试实现某种工厂模式。这是例子。我有两个方法“ getCat”和“ getDog”,每个方法采用不同的参数。以及映射密钥和相应方法的对象“宠物”。我正在尝试创建工厂“ getPet”,并传入“类型”和相应的参数。

但是我不确定如何键入“ arg”(现在是任何类型),以及如何限制类型是否为“ cat”,参数是否为“ cat”(具有喵声方法)?

interface CatArg {name: string; meow: () => string; }
interface DogArg {name: string; bark: () => string; }


function getCat({name: string, meow}: CatArg) {
    meow();
}

function getDog({name: string, bark}: DogArg) {
    bark();
}

const pet = {
    cat: getCat,
    dog: getDog
};

function playWithPet(type: 'cat' | 'dog', arg: any) {
    switch (type) {
        case 'cat':
            return pet.cat(arg);
        case 'dog':
            return pet.dog(arg);
    }
}

playWithPet('cat', {name: 'Kitty', meow: () => 'dont touch me'});
playWithPet('dog', {name: 'Bella', bark: () => 'play with me'});

2 个答案:

答案 0 :(得分:0)

您可以像这样使用函数重载

function playWithPet( type: 'cat', arg: CatArg): void
function playWithPet( type: 'dog', arg: DogArg ): void
function playWithPet( type, arg ) {
    switch (type) {
        case 'cat':
            return pet.cat(arg);
        case 'dog':
            return pet.dog(arg);
    }
}

注意:由于您的getCatgetDog没有返回任何内容,因此我返回的是void。因此,此函数应明确表明未返回任何内容,总体而言,我将重构代码。

现在它将检查是否为第二个参数传递了正确的对象

另一种方法是这种方式

interface PlayWithPet {
  ( type: 'cat', arg: CatArg ): void
  ( type: 'dog', arg: DogArg ): void
}

const playWithPet: PlayWithPet = ( type, arg ) => {
    switch (type) {
        case 'cat':
            return pet.cat(arg);
        case 'dog':
            return pet.dog(arg);
    }
}

答案 1 :(得分:0)

通常,TypeScript不鼓励这种用法,但在3.2+版本中,您可以通过将元组类型用于其余参数以及已区分的并集来使其工作:

function playWithPet(...args: ['cat', CatArg] | ['dog', DogArg]): void {
  switch (args[0]) {
  case 'cat':
    return pet.cat(args[1]);
  case 'dog':
    return pet.dog(args[1]);
  }
}