我是打字机的新手,并尝试实现某种工厂模式。这是例子。我有两个方法“ 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'});
答案 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);
}
}
注意:由于您的getCat
和getDog
没有返回任何内容,因此我返回的是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]);
}
}