Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,38 @@ const p: WithContext<Person> = {
};
```

### Merging multiple concrete types

Some Schema.org objects can legitimately carry multiple concrete `@type` values.
For those advanced cases, `schema-dts` exports leaf types alongside the usual
union aliases, plus a `MergeLeafTypes` helper for combining them:

```ts
import type {
MergeLeafTypes,
ProductLeaf,
SoftwareApplicationLeaf,
WithContext,
} from 'schema-dts';

const product: WithContext<
MergeLeafTypes<[ProductLeaf, SoftwareApplicationLeaf]>
> = {
'@context': 'https://schema.org',
'@type': ['Product', 'SoftwareApplication'],
name: 'My App',
offers: {
'@type': 'Offer',
price: 89,
priceCurrency: 'USD',
},
operatingSystem: 'Any',
};
```

`MergeLeafTypes` expects concrete leaf types such as `ProductLeaf`, not union
aliases such as `Product`.

### Graphs and IDs

JSON-LD supports `'@graph'` objects that have richer interconnected links
Expand Down
6 changes: 3 additions & 3 deletions packages/schema-dts-gen/src/ts/class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ export class Class {
assert(baseName, 'Expect baseName to exist when leafName exists.');

return factory.createInterfaceDeclaration(
/*modifiers=*/ [],
factory.createModifiersFromModifierFlags(ModifierFlags.Export),
leafName,
/*typeParameters=*/ [],
/*heritage=*/ [
Expand Down Expand Up @@ -385,7 +385,7 @@ export class Class {
// ... props;
// };
// // Leaf:
// export type XyzLeaf = XyzBase & {
// export interface XyzLeaf extends XyzBase {
// '@type': 'Xyz'
// }
// // Complete Type ----------------------------//
Expand Down Expand Up @@ -496,7 +496,7 @@ export class RoleBuiltin extends Builtin {
assert(baseName, 'Role must have Base Name.');

return factory.createTypeAliasDeclaration(
/*modifiers=*/ [],
factory.createModifiersFromModifierFlags(ModifierFlags.Export),
leafName,
/*typeParameters=*/ [
factory.createTypeParameterDeclaration(
Expand Down
11 changes: 11 additions & 0 deletions packages/schema-dts-gen/src/ts/helper_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ function GraphType(context: Context) {
}

const SchemaValueName = 'SchemaValue';
const MergeLeafTypesName = 'MergeLeafTypes';
export const IdReferenceName = 'IdReference';
export const GraphTypeName = 'Graph';

Expand Down Expand Up @@ -111,6 +112,11 @@ export function HelperTypes(context: Context, {hasRole}: {hasRole: boolean}) {
/*propertyName=*/ undefined,
/*name=*/ factory.createIdentifier('IdReference'),
),
factory.createImportSpecifier(
/*isTypeOnly=*/ false,
/*propertyName=*/ undefined,
/*name=*/ factory.createIdentifier(MergeLeafTypesName),
),
]),
),
factory.createStringLiteral('schema-dts-lib'),
Expand All @@ -129,6 +135,11 @@ export function HelperTypes(context: Context, {hasRole}: {hasRole: boolean}) {
/*propertyName=*/ undefined,
/*name=*/ factory.createIdentifier('IdReference'),
),
factory.createExportSpecifier(
/*isTypeOnly=*/ false,
/*propertyName=*/ undefined,
/*name=*/ factory.createIdentifier(MergeLeafTypesName),
),
]),
),
WithContextType(context),
Expand Down
8 changes: 4 additions & 4 deletions packages/schema-dts-gen/test/baselines/category_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ test(`baseline_${basename(import.meta.url)}`, async () => {
);

expect(actual).toMatchInlineSnapshot(`
"import type { JsonLdObject, IdReference } from "schema-dts-lib";
export type { JsonLdObject, IdReference };
"import type { JsonLdObject, IdReference, MergeLeafTypes } from "schema-dts-lib";
export type { JsonLdObject, IdReference, MergeLeafTypes };
/** Used at the top-level node to indicate the context for the JSON-LD objects used. The context provided in this type is compatible with the keys and URLs in the rest of this generated file. */
export type WithContext<T extends JsonLdObject | string> = T & {
"@context": "https://schema.org";
Expand All @@ -67,7 +67,7 @@ export type WithActionConstraints<T extends ActionBase> = T & InputActionConstra

export type Text = string;

interface DistilleryLeaf extends ThingBase {
export interface DistilleryLeaf extends ThingBase {
"@type": "Distillery";
}
/** A distillery. */
Expand All @@ -76,7 +76,7 @@ export type Distillery = DistilleryLeaf;
interface ThingBase extends Partial<IdReference> {
"name"?: SchemaValue<Text>;
}
interface ThingLeaf extends ThingBase {
export interface ThingLeaf extends ThingBase {
"@type": "Thing";
}
export type Thing = ThingLeaf | Distillery;
Expand Down
6 changes: 3 additions & 3 deletions packages/schema-dts-gen/test/baselines/comments_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ test(`baseline_${basename(import.meta.url)}`, async () => {
);

expect(actual).toMatchInlineSnapshot(`
"import type { JsonLdObject, IdReference } from "schema-dts-lib";
export type { JsonLdObject, IdReference };
"import type { JsonLdObject, IdReference, MergeLeafTypes } from "schema-dts-lib";
export type { JsonLdObject, IdReference, MergeLeafTypes };
/** Used at the top-level node to indicate the context for the JSON-LD objects used. The context provided in this type is compatible with the keys and URLs in the rest of this generated file. */
export type WithContext<T extends JsonLdObject | string> = T & {
"@context": "https://schema.org";
Expand Down Expand Up @@ -140,7 +140,7 @@ interface ThingBase extends Partial<IdReference> {
*/
"openingHours"?: SchemaValue<Text>;
}
interface ThingLeaf extends ThingBase {
export interface ThingLeaf extends ThingBase {
"@type": "Thing";
}
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ test(`baseline_${basename(import.meta.url)}`, async () => {
);

expect(actual).toMatchInlineSnapshot(`
"import type { JsonLdObject, IdReference } from "schema-dts-lib";
export type { JsonLdObject, IdReference };
"import type { JsonLdObject, IdReference, MergeLeafTypes } from "schema-dts-lib";
export type { JsonLdObject, IdReference, MergeLeafTypes };
/** Used at the top-level node to indicate the context for the JSON-LD objects used. The context provided in this type is compatible with the keys and URLs in the rest of this generated file. */
export type WithContext<T extends JsonLdObject | string> = T & {
"@context": "https://schema.org";
Expand Down Expand Up @@ -74,7 +74,7 @@ interface ThingBase extends Partial<IdReference> {
"age"?: SchemaValue<Number>;
"name"?: SchemaValue<Text>;
}
interface ThingLeaf extends ThingBase {
export interface ThingLeaf extends ThingBase {
"@type": "Thing";
}
export type Thing = ThingLeaf;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ test(`baseline_${basename(import.meta.url)}`, async () => {
);

expect(actual).toMatchInlineSnapshot(`
"import type { JsonLdObject, IdReference } from "schema-dts-lib";
export type { JsonLdObject, IdReference };
"import type { JsonLdObject, IdReference, MergeLeafTypes } from "schema-dts-lib";
export type { JsonLdObject, IdReference, MergeLeafTypes };
/** Used at the top-level node to indicate the context for the JSON-LD objects used. The context provided in this type is compatible with the keys and URLs in the rest of this generated file. */
export type WithContext<T extends JsonLdObject | string> = T & {
"@context": "https://schema.org";
Expand All @@ -52,7 +52,7 @@ export type WithActionConstraints<T extends ActionBase> = T & InputActionConstra

interface ThingBase extends Partial<IdReference> {
}
interface ThingLeaf extends ThingBase {
export interface ThingLeaf extends ThingBase {
"@type": "Thing";
}
export type Thing = ThingLeaf;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ test(`baseline_${basename(import.meta.url)}`, async () => {
);

expect(actual).toMatchInlineSnapshot(`
"import type { JsonLdObject, IdReference } from "schema-dts-lib";
export type { JsonLdObject, IdReference };
"import type { JsonLdObject, IdReference, MergeLeafTypes } from "schema-dts-lib";
export type { JsonLdObject, IdReference, MergeLeafTypes };
/** Used at the top-level node to indicate the context for the JSON-LD objects used. The context provided in this type is compatible with the keys and URLs in the rest of this generated file. */
export type WithContext<T extends JsonLdObject | string> = T & {
"@context": "https://schema.org";
Expand All @@ -93,15 +93,15 @@ export type Text = string;
interface CarBase extends ThingBase {
"doorNumber"?: SchemaValue<Number>;
}
interface CarLeaf extends CarBase {
export interface CarLeaf extends CarBase {
"@type": "Car";
}
export type Car = CarLeaf;

interface PersonLikeBase extends ThingBase {
"height"?: SchemaValue<Number>;
}
interface PersonLikeLeaf extends PersonLikeBase {
export interface PersonLikeLeaf extends PersonLikeBase {
"@type": "PersonLike";
}
export type PersonLike = PersonLikeLeaf;
Expand All @@ -122,7 +122,7 @@ interface ThingBase extends Partial<IdReference> {
*/
"names2"?: SchemaValue<Text>;
}
interface ThingLeaf extends ThingBase {
export interface ThingLeaf extends ThingBase {
"@type": "Thing";
}
export type Thing = ThingLeaf | Car | PersonLike | Vehicle;
Expand All @@ -132,7 +132,7 @@ interface VehicleBase extends ThingBase {
/** @deprecated Consider using http://schema.org/doorNumber instead. */
"doors"?: SchemaValue<Number>;
}
interface VehicleLeaf extends VehicleBase {
export interface VehicleLeaf extends VehicleBase {
"@type": "Vehicle";
}
/** @deprecated Use Car instead. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ test(`baseline_${basename(import.meta.url)}`, async () => {
);

expect(actual).toMatchInlineSnapshot(`
"import type { JsonLdObject, IdReference } from "schema-dts-lib";
export type { JsonLdObject, IdReference };
"import type { JsonLdObject, IdReference, MergeLeafTypes } from "schema-dts-lib";
export type { JsonLdObject, IdReference, MergeLeafTypes };
/** Used at the top-level node to indicate the context for the JSON-LD objects used. The context provided in this type is compatible with the keys and URLs in the rest of this generated file. */
export type WithContext<T extends JsonLdObject | string> = T & {
"@context": "https://schema.org";
Expand Down Expand Up @@ -76,7 +76,7 @@ interface ThingBase extends Partial<IdReference> {
*/
"name"?: SchemaValue<Text>;
}
interface ThingLeaf extends ThingBase {
export interface ThingLeaf extends ThingBase {
"@type": "Thing";
}
/**
Expand Down
6 changes: 3 additions & 3 deletions packages/schema-dts-gen/test/baselines/enum_skipped_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ test(`baseline_${basename(import.meta.url)}`, async () => {
);

expect(actual).toMatchInlineSnapshot(`
"import type { JsonLdObject, IdReference } from "schema-dts-lib";
export type { JsonLdObject, IdReference };
"import type { JsonLdObject, IdReference, MergeLeafTypes } from "schema-dts-lib";
export type { JsonLdObject, IdReference, MergeLeafTypes };
/** Used at the top-level node to indicate the context for the JSON-LD objects used. The context provided in this type is compatible with the keys and URLs in the rest of this generated file. */
export type WithContext<T extends JsonLdObject | string> = T & {
"@context": "https://schema.org";
Expand All @@ -65,7 +65,7 @@ export type WithActionConstraints<T extends ActionBase> = T & InputActionConstra

interface ThingBase extends Partial<IdReference> {
}
interface ThingLeaf extends ThingBase {
export interface ThingLeaf extends ThingBase {
"@type": "Thing";
}
/** A Thing! */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ test(`baseline_${basename(import.meta.url)}`, async () => {
);

expect(actual).toMatchInlineSnapshot(`
"import type { JsonLdObject, IdReference } from "schema-dts-lib";
export type { JsonLdObject, IdReference };
"import type { JsonLdObject, IdReference, MergeLeafTypes } from "schema-dts-lib";
export type { JsonLdObject, IdReference, MergeLeafTypes };
/** Used at the top-level node to indicate the context for the JSON-LD objects used. The context provided in this type is compatible with the keys and URLs in the rest of this generated file. */
export type WithContext<T extends JsonLdObject | string> = T & {
"@context": "https://schema.org";
Expand All @@ -74,23 +74,23 @@ export type Text = string;
interface PersonLikeBase extends ThingBase {
"height"?: SchemaValue<Number>;
}
interface PersonLikeLeaf extends PersonLikeBase {
export interface PersonLikeLeaf extends PersonLikeBase {
"@type": "PersonLike";
}
export type PersonLike = PersonLikeLeaf;

interface ThingBase extends Partial<IdReference> {
"name"?: SchemaValue<Text>;
}
interface ThingLeaf extends ThingBase {
export interface ThingLeaf extends ThingBase {
"@type": "Thing";
}
export type Thing = ThingLeaf | PersonLike | Vehicle;

interface VehicleBase extends ThingBase {
"doors"?: SchemaValue<Number>;
}
interface VehicleLeaf extends VehicleBase {
export interface VehicleLeaf extends VehicleBase {
"@type": "Vehicle";
}
export type Vehicle = VehicleLeaf;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ test(`baseline_${basename(import.meta.url)}`, async () => {
);

expect(actual).toMatchInlineSnapshot(`
"import type { JsonLdObject, IdReference } from "schema-dts-lib";
export type { JsonLdObject, IdReference };
"import type { JsonLdObject, IdReference, MergeLeafTypes } from "schema-dts-lib";
export type { JsonLdObject, IdReference, MergeLeafTypes };
/** Used at the top-level node to indicate the context for the JSON-LD objects used. The context provided in this type is compatible with the keys and URLs in the rest of this generated file. */
export type WithContext<T extends JsonLdObject | string> = T & {
"@context": "https://schema.org";
Expand All @@ -69,15 +69,15 @@ export type Text = string;
interface PersonLikeBase extends ThingBase {
"height"?: SchemaValue<Number>;
}
interface PersonLikeLeaf extends PersonLikeBase {
export interface PersonLikeLeaf extends PersonLikeBase {
"@type": "PersonLike";
}
export type PersonLike = PersonLikeLeaf;

interface ThingBase extends Partial<IdReference> {
"name"?: SchemaValue<Text>;
}
interface ThingLeaf extends ThingBase {
export interface ThingLeaf extends ThingBase {
"@type": "Thing";
}
export type Thing = ThingLeaf | PersonLike;
Expand Down
12 changes: 6 additions & 6 deletions packages/schema-dts-gen/test/baselines/nested_datatype_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ test(`baseline_${basename(import.meta.url)}`, async () => {
);

expect(actual).toMatchInlineSnapshot(`
"import type { JsonLdObject, IdReference } from "schema-dts-lib";
export type { JsonLdObject, IdReference };
"import type { JsonLdObject, IdReference, MergeLeafTypes } from "schema-dts-lib";
export type { JsonLdObject, IdReference, MergeLeafTypes };
/** Used at the top-level node to indicate the context for the JSON-LD objects used. The context provided in this type is compatible with the keys and URLs in the rest of this generated file. */
export type WithContext<T extends JsonLdObject | string> = T & {
"@context": "https://schema.org";
Expand All @@ -82,12 +82,12 @@ export type Text = PronounceableText | URL | string;
interface ArabicTextBase extends PronounceableTextBase {
"arabicPhoneticText"?: SchemaValue<Text>;
}
interface ArabicTextLeaf extends ArabicTextBase {
export interface ArabicTextLeaf extends ArabicTextBase {
"@type": "ArabicText";
}
export type ArabicText = ArabicTextLeaf | string;

interface EnglishTextLeaf extends PronounceableTextBase {
export interface EnglishTextLeaf extends PronounceableTextBase {
"@type": "EnglishText";
}
export type EnglishText = EnglishTextLeaf | string;
Expand All @@ -97,7 +97,7 @@ export type FancyURL = string;
interface PronounceableTextBase extends Partial<IdReference> {
"phoneticText"?: SchemaValue<Text>;
}
interface PronounceableTextLeaf extends PronounceableTextBase {
export interface PronounceableTextLeaf extends PronounceableTextBase {
"@type": "PronounceableText";
}
export type PronounceableText = PronounceableTextLeaf | ArabicText | EnglishText | string;
Expand All @@ -107,7 +107,7 @@ interface ThingBase extends Partial<IdReference> {
"pronunciation"?: SchemaValue<PronounceableText | IdReference>;
"website"?: SchemaValue<URL>;
}
interface ThingLeaf extends ThingBase {
export interface ThingLeaf extends ThingBase {
"@type": "Thing";
}
export type Thing = ThingLeaf;
Expand Down
Loading
Loading