我对打字稿很陌生,正在开发的应用程序中遇到了一个问题。
export abstract class DiskElement{
id:string;
filename:string;
}
export class File extends DiskElement{
size:number;
}
export class Directory extends DiskElement{
children:DiskElement[];
}
export class User{
shares:DiskElement[];
}
我的问题是,当我从Json文件加载用户时,它说size属性不属于DiskElement类型。
我通过将share / children声明为(File | Directory)[]来解决了我的问题,但是从长远来看,我认为这种解决方案是不可维持的。我的应用程序中有多个“父”类的数组,每当我添加新的subType时,都必须修改集合的每个声明。
我很确定有一个非常简单且不错的解决方案。
我如何加载它:
users : User = {
shares:
[
{
id:"{123-12312312-12312}",
filename:"test.jpg",
size:123123000
},
{
id:"{222-2222222-22222}",
filename:"testFolder",
children:[{...},{...}]
}
]};
它位于模拟“数据集”中,但不会与我上面解释的错误一起编译,大小不是DiskElement的属性。
将用户更改为:
export class User{
shares:(File|Directory)[];
}
这有效,正如@Jonas Wilms指出的那样,我可以定义一个新的联合类型,即File | Directory,并确保将来在我将DiskElement子类化时更新该类型,但是我仍然觉得自己缺少一些东西
答案 0 :(得分:0)
您可以将size
设置为可选属性:
export abstract class DiskElement{
id:string;
filename:string;
size?: number;
}
或者如果有多个可能的子类,例如File
和Blob
:
export abstract class DiskElement{
id:string;
filename:string;
}
class File extends DiskElement {
size: number;
}
class Blob extends DiskElement {
length: number;
}
然后您可以使用联合类型在磁盘上键入内容:
type Data = File | Blob;
这样,您可以在任何地方使用Data
并轻松添加新类型。要访问该大小,您必须添加一个typeguard:
var sth: Data = new File();
if(sth instanceof File) { // sth: Data -> File
console.log(sth.size); // works
}
答案 1 :(得分:0)
好吧,我知道了...
在javascript中,
之间没有太大区别var users = { prop1:"zzz", prop2:"aaaa"}; //(json without quotes)
var users = JSON.parse(json);
结果证明在打字稿中显然不是真的。 因此,我上面的示例变为:
users : User = JSON.parse(`
{
shares:
[
{
id:"{123-12312312-12312}",
filename:"test.jpg",
size:123123000
},
{
id:"{222-2222222-22222}",
filename:"testFolder",
children:[{...},{...}]
}
]
}`);
这种方式可以正常工作。