使用递归的 Typescript 接口 JSON
Using Typescript Interface with a Recursive JSON
我正在尝试使用 JSON 调整产品的 ontology 及其属性。下面提到的 JSON 结构是我正在考虑的。
Each Product (Concept) has two types of properties:
1. Data Properties 2. Object Properties
使用 Protege 时这些属性的典型定义如下SO Thread:
In Protégé there are are different tabs for creating Object Properties and Datatype Properties. If a property should relate individuals to individuals, then it needs to be an object property, and if it relates individuals to literals, then it needs to be a datatype property.
我认为每个 属性 都具有以下属性:
name: string
url: string
type: dataprop or objprop
objPropSource: available only for Objproperties
我画了一个小递归JSON如下:
{
"name": "chair",
"url": "http://namespace.org#chair",
"type": "main",
"properties": [
{
"name": "height",
"url": "http://namespace.org#height",
"type": "dataprop"
},
{
"name": "width",
"url": "http://namespace.org#width",
"type": "dataprop"
},
{
"name": "horizontalsurface",
"url": "http://namespace.org#horizontalsurface",
"type": "objprop",
"objPropSource": "http://namespace.org#hasHorizontalSurface",
"properties": [
{
"name": "Legislation",
"url": "http://namespace.org#legislation",
"type": "objprop",
"objPropSource": "http://namespace.org#compliesWithLegislation",
"properties": [
{
"name": "hasLegislationName",
"url": "http://namespace.org#hasLegislationName",
"type": "dataprop"
}
]
}
]
},
{
"name": "legislation",
"url": "http://namespace.org#legislation",
"type": "objprop",
"objPropSource": "http://namespace.org#compliesWithLegistion",
"properties": [
{
"name": "hasLegislationName",
"url": "http://namespace.org#hasLegislationName",
"type": "dataprop"
}
]
}
]
}
在某种程度上,结构为椅子提供了一个二叉树,其中有 height
、width
等 dataproperties 和 horizontalsurface
和legislation
作为对象属性
JSON 到 Typescript 中的接口
我使用 JSON to TS Online Converter 查看 JSON 将如何转换为 Typescript 接口,结果如下:
interface RootObject {
name: string;
url: string;
type: string;
properties: Property3[];
}
interface Property3 {
name: string;
url: string;
type: string;
objPropSource?: string;
properties?: Property2[];
}
interface Property2 {
name: string;
url: string;
type: string;
objPropSource?: string;
properties?: Property[];
}
interface Property {
name: string;
url: string;
type: string;
}
推理
我推断使用递归接口的方法 JSON 是不可扩展的,因为这样的 Ontology 产品可以扩展到 1000 个属性和属性中的属性。正如上面提到的示例所示,对于父级 属性 中的每个 属性 都会继续创建接口。
预期
我应该使用具有这种 JSON 结构的 Typescript 接口,还是应该坚持创建 Class 然后按照创建二叉树的传统方法即
export class leaf {
name: string;
url: string;
type: string;
children: leaf[] = [];
}
然后写一个递归直到解析完整的结构?
TL;DR
Can Typescript interfaces be used for Large Recursive JSON Structures?
您应该能够将该结构很好地表示为递归接口:
interface Property {
name: string;
url: string;
type: string;
objPropSource?: string;
properties?: Property[];
}
您尝试使用的 JSON 到 TS 转换器似乎没有识别结构递归性质的功能。
工作示例:
interface Property {
name: string;
url: string;
type: string;
objPropSource?: string; // optional property
properties?: Property[];
};
var p: Property = JSON.parse(getJson());
alert(p.properties[2].properties[0].name);
alert(p.properties[3].objPropSource);
function getJson() {
return `{
"name": "chair",
"url": "http://namespace.org#chair",
"type": "main",
"properties": [
{
"name": "height",
"url": "http://namespace.org#height",
"type": "dataprop"
},
{
"name": "width",
"url": "http://namespace.org#width",
"type": "dataprop"
},
{
"name": "horizontalsurface",
"url": "http://namespace.org#horizontalsurface",
"type": "objprop",
"objPropSource": "http://namespace.org#hasHorizontalSurface",
"properties": [
{
"name": "Legislation",
"url": "http://namespace.org#legislation",
"type": "objprop",
"objPropSource": "http://namespace.org#compliesWithLegislation",
"properties": [
{
"name": "hasLegislationName",
"url": "http://namespace.org#hasLegislationName",
"type": "dataprop"
}
]
}
]
},
{
"name": "legislation",
"url": "http://namespace.org#legislation",
"type": "objprop",
"objPropSource": "http://namespace.org#compliesWithLegistion",
"properties": [
{
"name": "hasLegislationName",
"url": "http://namespace.org#hasLegislationName",
"type": "dataprop"
}
]
}
]
}`;
}
两个可能的帮手,让您以后更轻松。
type MakeRecusive<Keys extends string, T> = {
[K in Keys]: T & MakeRecusive<K, T>
} & T
type MakeRecusiveObectKeys<TKeys extends string, T> = {
[K in keyof T]: K extends TKeys ? T[K] & MakeRecusive<K, T[K]>: T[K]
}
鉴别器类型:
type BaseTypes = 'dataprop' | 'objprop'
interface BaseType<TType extends BaseTypes = 'dataprop'> {
name: string;
url: string;
type: TType;
properties?: DiscriminatorType
}
interface ObjProp extends BaseType<'objprop'>{
objPropSource: string;
}
type DiscriminatorType = BaseType | ObjProp
const root: DiscriminatorType = {
name:'name',
type: 'dataprop',
url:'string',
properties: {
name:'name2',
type:'objprop',
objPropSource:'sdf',
url:'str',
}
}
我正在尝试使用 JSON 调整产品的 ontology 及其属性。下面提到的 JSON 结构是我正在考虑的。
Each Product (Concept) has two types of properties: 1. Data Properties 2. Object Properties
使用 Protege 时这些属性的典型定义如下SO Thread:
In Protégé there are are different tabs for creating Object Properties and Datatype Properties. If a property should relate individuals to individuals, then it needs to be an object property, and if it relates individuals to literals, then it needs to be a datatype property.
我认为每个 属性 都具有以下属性:
name: string
url: string
type: dataprop or objprop
objPropSource: available only for Objproperties
我画了一个小递归JSON如下:
{
"name": "chair",
"url": "http://namespace.org#chair",
"type": "main",
"properties": [
{
"name": "height",
"url": "http://namespace.org#height",
"type": "dataprop"
},
{
"name": "width",
"url": "http://namespace.org#width",
"type": "dataprop"
},
{
"name": "horizontalsurface",
"url": "http://namespace.org#horizontalsurface",
"type": "objprop",
"objPropSource": "http://namespace.org#hasHorizontalSurface",
"properties": [
{
"name": "Legislation",
"url": "http://namespace.org#legislation",
"type": "objprop",
"objPropSource": "http://namespace.org#compliesWithLegislation",
"properties": [
{
"name": "hasLegislationName",
"url": "http://namespace.org#hasLegislationName",
"type": "dataprop"
}
]
}
]
},
{
"name": "legislation",
"url": "http://namespace.org#legislation",
"type": "objprop",
"objPropSource": "http://namespace.org#compliesWithLegistion",
"properties": [
{
"name": "hasLegislationName",
"url": "http://namespace.org#hasLegislationName",
"type": "dataprop"
}
]
}
]
}
在某种程度上,结构为椅子提供了一个二叉树,其中有 height
、width
等 dataproperties 和 horizontalsurface
和legislation
作为对象属性
JSON 到 Typescript 中的接口
我使用 JSON to TS Online Converter 查看 JSON 将如何转换为 Typescript 接口,结果如下:
interface RootObject {
name: string;
url: string;
type: string;
properties: Property3[];
}
interface Property3 {
name: string;
url: string;
type: string;
objPropSource?: string;
properties?: Property2[];
}
interface Property2 {
name: string;
url: string;
type: string;
objPropSource?: string;
properties?: Property[];
}
interface Property {
name: string;
url: string;
type: string;
}
推理
我推断使用递归接口的方法 JSON 是不可扩展的,因为这样的 Ontology 产品可以扩展到 1000 个属性和属性中的属性。正如上面提到的示例所示,对于父级 属性 中的每个 属性 都会继续创建接口。
预期
我应该使用具有这种 JSON 结构的 Typescript 接口,还是应该坚持创建 Class 然后按照创建二叉树的传统方法即
export class leaf {
name: string;
url: string;
type: string;
children: leaf[] = [];
}
然后写一个递归直到解析完整的结构?
TL;DR
Can Typescript interfaces be used for Large Recursive JSON Structures?
您应该能够将该结构很好地表示为递归接口:
interface Property {
name: string;
url: string;
type: string;
objPropSource?: string;
properties?: Property[];
}
您尝试使用的 JSON 到 TS 转换器似乎没有识别结构递归性质的功能。
工作示例:
interface Property {
name: string;
url: string;
type: string;
objPropSource?: string; // optional property
properties?: Property[];
};
var p: Property = JSON.parse(getJson());
alert(p.properties[2].properties[0].name);
alert(p.properties[3].objPropSource);
function getJson() {
return `{
"name": "chair",
"url": "http://namespace.org#chair",
"type": "main",
"properties": [
{
"name": "height",
"url": "http://namespace.org#height",
"type": "dataprop"
},
{
"name": "width",
"url": "http://namespace.org#width",
"type": "dataprop"
},
{
"name": "horizontalsurface",
"url": "http://namespace.org#horizontalsurface",
"type": "objprop",
"objPropSource": "http://namespace.org#hasHorizontalSurface",
"properties": [
{
"name": "Legislation",
"url": "http://namespace.org#legislation",
"type": "objprop",
"objPropSource": "http://namespace.org#compliesWithLegislation",
"properties": [
{
"name": "hasLegislationName",
"url": "http://namespace.org#hasLegislationName",
"type": "dataprop"
}
]
}
]
},
{
"name": "legislation",
"url": "http://namespace.org#legislation",
"type": "objprop",
"objPropSource": "http://namespace.org#compliesWithLegistion",
"properties": [
{
"name": "hasLegislationName",
"url": "http://namespace.org#hasLegislationName",
"type": "dataprop"
}
]
}
]
}`;
}
两个可能的帮手,让您以后更轻松。
type MakeRecusive<Keys extends string, T> = {
[K in Keys]: T & MakeRecusive<K, T>
} & T
type MakeRecusiveObectKeys<TKeys extends string, T> = {
[K in keyof T]: K extends TKeys ? T[K] & MakeRecusive<K, T[K]>: T[K]
}
鉴别器类型:
type BaseTypes = 'dataprop' | 'objprop'
interface BaseType<TType extends BaseTypes = 'dataprop'> {
name: string;
url: string;
type: TType;
properties?: DiscriminatorType
}
interface ObjProp extends BaseType<'objprop'>{
objPropSource: string;
}
type DiscriminatorType = BaseType | ObjProp
const root: DiscriminatorType = {
name:'name',
type: 'dataprop',
url:'string',
properties: {
name:'name2',
type:'objprop',
objPropSource:'sdf',
url:'str',
}
}