Typescript 模式匹配开关语句
假设我有返回动物信息的API。然而,每种动物的json有效载荷都有很大差异,即使许多属性是通用的和强制性的 我想为这些不同的动物中的每一个创建一个“强类型”类型脚本类,这样我的代码就不会变得一团糟。每种动物都需要非常独特和具体的处理 正确的做法是什么?基本上,我想完成以下任务:Typescript 模式匹配开关语句,typescript,typescript-generics,react-typescript,Typescript,Typescript Generics,React Typescript,假设我有返回动物信息的API。然而,每种动物的json有效载荷都有很大差异,即使许多属性是通用的和强制性的 我想为这些不同的动物中的每一个创建一个“强类型”类型脚本类,这样我的代码就不会变得一团糟。每种动物都需要非常独特和具体的处理 正确的做法是什么?基本上,我想完成以下任务: interface Animal { Name: string; Weight: number; } interface Insect extends Animal { AmountOfEyes
interface Animal {
Name: string;
Weight: number;
}
interface Insect extends Animal {
AmountOfEyes: number;
}
interface Bird extends Animal {
PlumageColor : string;
}
function OnlyForBirds(bird: Bird)
{
// do something birdly
}
function OnlyForInsects(insect: Insect)
{
// do something creepy
}
function GetAnimal(animalId: string) : Promise<Animal>
{
const uri = `${baseURL}/${animalId}`;
// fetches the json response body from http request
const result = await get<any>(uri);
switch(animal.Name)
{
case 'Insect':
return result as Insect;
case ...
...
}
// throw unhandled
}
function ProcessAnimal(animalId:string) : Promise
{
let animal = await GetAnimal(animalId);
// how do I do this now? Can't I use something over tye interface
// types instead of using the .Name and casting again?
// is there any advisable standard I can use?
if(animal is a bird){
OnlyForBirds(bird)
}
else if(animal is an insect){
OnlyForInsects(insect)
}
}
界面动物{
名称:字符串;
重量:个数;
}
昆虫与动物的界面{
是:数字;
}
鸟类与动物的接口{
羽毛颜色:弦;
}
功能仅适用于鸟(鸟:鸟)
{
//做傻事
}
功能仅适用于昆虫(昆虫:昆虫)
{
//做些令人毛骨悚然的事
}
函数GetAnimal(animalId:string):Promise
{
常量uri=`${baseURL}/${animalId}`;
//从http请求获取json响应正文
const result=等待获取(uri);
开关(动物名称)
{
“昆虫”一案:
返回结果为昆虫;
案例
...
}
//未经处理的抛掷
}
函数ProcessAnimal(animalId:string):Promise
{
让动物=等待得到动物(动物);
//我现在该怎么做?我不能通过tye接口使用一些东西吗
//键入而不是使用.Name并再次强制转换?
//有什么可取的标准我可以使用吗?
如果(动物是鸟){
仅鸟(鸟)
}
否则,如果(动物是昆虫){
仅限昆虫类
}
}
任何建议,包括不要使用这样的接口,我都会很感激。我想出来了。一些很深的黑暗魔法。 在基本接口中定义枚举属性。每一个新的不同类型的类,或者在本例中的动物,都会为自己指定这些属性中的一个。打开此属性,并在该属性中键入动物
enum AnimalType {
Insect = "Insect",
Bird = "Bird"
}
interface Animal {
Type: AnimalType;
Weight: number;
}
interface Insect extends Animal {
Type: AnimalType.Insect; // MAGIC BREWING
AmountOfEyes: number;
}
interface Bird extends Animal {
Type: AnimalType.Bird; // MAGIC BREWING
PlumageColor : string;
}
function OnlyForBirds(bird: Bird)
{
// do something birdly
}
function OnlyForInsects(insect: Insect)
{
// do something creepy
}
function GetAnimal(animalId: string) : Promise<Animal>
{
const uri = `${baseURL}/${animalId}`;
// fetches the json response body from http request
const result = await get<any>(uri);
switch(animal.Type)
{
case 'Insect':
return result as Insect;
case ...
...
}
// throw unhandled
}
function ProcessAnimal(animalId:string) : Promise
{
let animal = await GetAnimal(animalId);
switch(animal.AnimalType){
case AnimalType.Insect:
OnlyForInsects(animal); // within this case clause, animal is typed as an Insect! MAGIC!
break;
case AnimalType.Bird:
OnlyForBirds(animal); // within this case clause, animal is typed as an bird! Go free little bird!
break;
default:
// throw
}
}
enum AnimalType{
昆虫=“昆虫”,
Bird=“Bird”
}
界面动物{
类型:动物型;
重量:个数;
}
昆虫与动物的界面{
类型:AnimalType.昆虫;//神奇酿造
是:数字;
}
鸟类与动物的接口{
类型:AnimalType.Bird;//魔法酿造
羽毛颜色:弦;
}
功能仅适用于鸟(鸟:鸟)
{
//做傻事
}
功能仅适用于昆虫(昆虫:昆虫)
{
//做些令人毛骨悚然的事
}
函数GetAnimal(animalId:string):Promise
{
常量uri=`${baseURL}/${animalId}`;
//从http请求获取json响应正文
const result=等待获取(uri);
开关(动物型)
{
“昆虫”一案:
返回结果为昆虫;
案例
...
}
//未经处理的抛掷
}
函数ProcessAnimal(animalId:string):Promise
{
让动物=等待得到动物(动物);
开关(动物。动物类型){
案例动物类型。昆虫:
OnlyForInsects(animal);//在这个case子句中,animal被键入为昆虫!MAGIC!
打破
案例动物类型。鸟类:
onlyforbird(animal);//在这个case子句中,animal被键入为bird!放开小鸟!
打破
违约:
//扔
}
}
对于您的用例,您发布的答案可能是最好的解决方案。我只是想用一种不同的方法来插话。如果您想要有多个继承层,那么您的解决方案开始崩溃,其中Duck
扩展Bird
。如果要查找动物
是否与基本鸟
界面匹配,可以定义一个自定义函数,查看对象的属性,查看对象是否具有羽毛颜色
。如果是这样,那么typescript就知道可以将其用作鸟
这是基本版本。我们说animal
有一个可选属性PlumageColor
,这样即使未定义
,我们也可以无误地访问它。然后我们检查PlumageColor
是否已定义,并且它是字符串
const isBird = (animal: Animal & {PlumageColor?: any}): animal is Bird => {
return typeof animal.PlumageColor === "string";
}
此版本更好,因为它断言动物
是鸟
,同时还保留了关于动物
的任何其他类型信息
const isBird = <T extends Animal & {PlumageColor?: any}>(animal: T): animal is T & Bird => {
return typeof animal.PlumageColor === "string";
}
const-isBird=(动物:T):动物是T&Bird=>{
返回typeof animal.PlumageColor==“string”;
}