对象中对象的高级类型
Advanced Types in Object in Object
我不知道如何在对象中使用多个高级类型。
我在父组件中有一个对象 Animal 并且在某些情况下起作用,我必须显示与特定类型相关的子组件;但我有以下错误,不知道解决方案。
interface Animal {
name: string;
age: number;
type: Bird | Fish;
}
interface Bird {
fly(): void;
}
interface Fish {
swim(): void;
}
Property 'swim' does not exist on type 'Bird | Fish'. Property 'swim' does not exist on type 'Bird'.
我试图在 typescript doc 中找到一些东西,但我没有找到任何解决方案。
高级示例:
interface.ts:
interface Animal {
id: number;
code: string;
metadata: Bird | Fish;
}
interface basicForm {
formLabel: string;
}
interface Bird extends basicForm {
name: string;
age: number;
fly: string;
}
interface Fish extends basicForm {
name: string;
age: number;
swim: string;
}
父组件html:
<ng-container [ngSwitch]="formLabel">
<app-fish-form *ngSwitchCase="'fishForm'" [detail]="detail"></app-fish-form>
<app-bird-form *ngSwitchCase="'birdForm'" [detail]="detail"></app-bird-form>
</ng-container>
父组件 ts:
public detail: Animal;
constructor() { }
ngOnInit() {
this._checkForm();
}
private _checkForm() {
// res should be fishForm or birdForm
*backendCall*then(res => this.detail.metadata.formLabel = res)
}
子组件(鱼)html:
<input type="text" name="swim" [(ngModel)]="detail.swim" />
子组件(鱼)ts:
@Input() detail: Animal;
ngOnInit() {
this.detail.metadata.swim = 'yes';
}
在我看来,如果在子组件的初始化时我能够将 this.detail.metadata as Fish;
我不知道你为什么直接在 type
上呼叫 swim()
或 fly()
。继承用于根据其类型以不同的方式实现相同的方法。
下面我会给你一个类似于你正在做的解决方案,但它意味着是你的接口的包装器而不是它们应该继承的父 class .
继承主要是为了做这样的事情:
interface Animal {
name: string;
code: string;
move: ()=> void;
}
class Fish implements Animal {
name: string;
code: string;
constructor(name: string, code: string) {
this.name = name;
this.code = code;
}
move() {
console.log("I'm swimming...");
}
}
class Bird implements Animal {
name: string;
code: string;
constructor(name: string, code: string) {
this.name = name;
this.code = code;
}
move() {
console.log("I'm flying...");
}
}
如您所见,鸟类和鱼类都执行相同的方法move()
,但它们的行为不同。这是继承的主要目的,“最终”继承对象通常是 class 而不是接口。
另一方面,如果您只需要一个 wrapper 用于一系列 classes,而不是使用继承,我建议您采用这种方法:
interface Bird {
name: string
age: number
type: 'BIRD'
fly: ()=>void
}
interface Fish {
name: string
age: number
type: 'FISH'
swim: ()=>void
}
type Animal = Fish | Bird;
let my_animal: Animal = {
name: 'Karl'
age: 8
type: 'FISH' as 'FISH'
swim: () => { console.log("I'm swimming...") }
}
if(my_animal.type === 'FISH'){
my_animal.swim(); //Typescript will not complain here
}
在这种情况下,动物充当包装纸。
我不知道如何在对象中使用多个高级类型。 我在父组件中有一个对象 Animal 并且在某些情况下起作用,我必须显示与特定类型相关的子组件;但我有以下错误,不知道解决方案。
interface Animal {
name: string;
age: number;
type: Bird | Fish;
}
interface Bird {
fly(): void;
}
interface Fish {
swim(): void;
}
Property 'swim' does not exist on type 'Bird | Fish'. Property 'swim' does not exist on type 'Bird'.
我试图在 typescript doc 中找到一些东西,但我没有找到任何解决方案。
高级示例:
interface.ts:
interface Animal {
id: number;
code: string;
metadata: Bird | Fish;
}
interface basicForm {
formLabel: string;
}
interface Bird extends basicForm {
name: string;
age: number;
fly: string;
}
interface Fish extends basicForm {
name: string;
age: number;
swim: string;
}
父组件html:
<ng-container [ngSwitch]="formLabel">
<app-fish-form *ngSwitchCase="'fishForm'" [detail]="detail"></app-fish-form>
<app-bird-form *ngSwitchCase="'birdForm'" [detail]="detail"></app-bird-form>
</ng-container>
父组件 ts:
public detail: Animal;
constructor() { }
ngOnInit() {
this._checkForm();
}
private _checkForm() {
// res should be fishForm or birdForm
*backendCall*then(res => this.detail.metadata.formLabel = res)
}
子组件(鱼)html:
<input type="text" name="swim" [(ngModel)]="detail.swim" />
子组件(鱼)ts:
@Input() detail: Animal;
ngOnInit() {
this.detail.metadata.swim = 'yes';
}
在我看来,如果在子组件的初始化时我能够将 this.detail.metadata as Fish;
我不知道你为什么直接在 type
上呼叫 swim()
或 fly()
。继承用于根据其类型以不同的方式实现相同的方法。
下面我会给你一个类似于你正在做的解决方案,但它意味着是你的接口的包装器而不是它们应该继承的父 class .
继承主要是为了做这样的事情:
interface Animal {
name: string;
code: string;
move: ()=> void;
}
class Fish implements Animal {
name: string;
code: string;
constructor(name: string, code: string) {
this.name = name;
this.code = code;
}
move() {
console.log("I'm swimming...");
}
}
class Bird implements Animal {
name: string;
code: string;
constructor(name: string, code: string) {
this.name = name;
this.code = code;
}
move() {
console.log("I'm flying...");
}
}
如您所见,鸟类和鱼类都执行相同的方法move()
,但它们的行为不同。这是继承的主要目的,“最终”继承对象通常是 class 而不是接口。
另一方面,如果您只需要一个 wrapper 用于一系列 classes,而不是使用继承,我建议您采用这种方法:
interface Bird {
name: string
age: number
type: 'BIRD'
fly: ()=>void
}
interface Fish {
name: string
age: number
type: 'FISH'
swim: ()=>void
}
type Animal = Fish | Bird;
let my_animal: Animal = {
name: 'Karl'
age: 8
type: 'FISH' as 'FISH'
swim: () => { console.log("I'm swimming...") }
}
if(my_animal.type === 'FISH'){
my_animal.swim(); //Typescript will not complain here
}
在这种情况下,动物充当包装纸。