Skip to content

Commit

Permalink
feat(heritage): Add support for interface heritage
Browse files Browse the repository at this point in the history
This enables converting interfaces extending other interfaces from typescript:

interface A extends B { ... }

To in core-types let A become an and-type of ref B and an object.

Reconstruction backwards works too.
  • Loading branch information
grantila committed Apr 3, 2023
1 parent 68f51a7 commit 4dc6953
Show file tree
Hide file tree
Showing 6 changed files with 853 additions and 37 deletions.
59 changes: 59 additions & 0 deletions lib/__snapshots__/core-types-to-ts.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,64 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`core-types-to-ts and-type as empty interface with 1 heritage 1`] = `
"export interface foo extends bar {
}
export interface bar {
b: number;
}
"
`;

exports[`core-types-to-ts and-type as empty interface with 2 heritage 1`] = `
"export interface foo extends bar, baz {
}
export interface bar {
b: number;
}
export interface baz {
z: boolean;
}
"
`;

exports[`core-types-to-ts and-type as non-empty interface with 1 heritage 1`] = `
"export interface foo extends bar {
f: string;
}
export interface bar {
b: number;
}
"
`;

exports[`core-types-to-ts and-type as non-empty interface with 2 heritage 1`] = `
"export interface foo extends bar, baz {
f: string;
}
export interface bar {
b: number;
}
export interface baz {
z: boolean;
}
"
`;

exports[`core-types-to-ts and-type that cannot be an interface because non-object ref 1`] = `
"export type foo = {
f?: string;
} & bar;
export type bar = null;
"
`;

exports[`core-types-to-ts complex type 1`] = `
{
"convertedTypes": [
Expand Down
43 changes: 43 additions & 0 deletions lib/bi-directional.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,49 @@ export type Bak = 17;
`export type Foo_Bar_Baz = 42;
export type Bak = 17;
`
);
} );

it( "handle extending two interfaces (include-if-referenced)", ( ) =>
{
const coreTypes = convertTypeScriptToCoreTypes(
`
interface A {
a: 'a';
}
export interface B {
b: 'b';
}
export interface C extends A, B {
c: 'c';
}
`,
{
nonExported: 'include-if-referenced'
}
);

const ts = convertCoreTypesToTypeScript(
coreTypes.data,
{
noDescriptiveHeader: true,
noDisableLintHeader: true,
}
);

expect( ts.data ).toBe(
`export interface B {
b: "b";
}
export interface C extends A, B {
c: "c";
}
export interface A {
a: "a";
}
`
);
} );
Expand Down
191 changes: 191 additions & 0 deletions lib/core-types-to-ts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,4 +280,195 @@ describe( "core-types-to-ts", ( ) =>

expect( ts.data ).toMatchSnapshot( );
} );

it( "and-type that cannot be an interface because non-object ref", ( ) =>
{
const ts = convertCoreTypesToTypeScript( wrapDocument( [
{
name: 'foo',
type: 'and',
and: [
{
type: 'object',
properties: {
f: { required: false, node: { type: 'string' } },
},
additionalProperties: false,
},
{
type: 'ref',
ref: 'bar',
},
],
},
{
name: 'bar',
type: 'null',
},
] ),
{ noDescriptiveHeader: true, noDisableLintHeader: true }
);

expect( ts.data ).toMatchSnapshot( );
} );

it( "and-type as empty interface with 1 heritage", ( ) =>
{
const ts = convertCoreTypesToTypeScript( wrapDocument( [
{
name: 'foo',
type: 'and',
and: [
{
type: 'object',
properties: { },
additionalProperties: false,
},
{
type: 'ref',
ref: 'bar',
},
],
},
{
name: 'bar',
type: 'object',
properties: {
b: { required: true, node: { type: 'number' } },
},
additionalProperties: false,
},
] ),
{ noDescriptiveHeader: true, noDisableLintHeader: true }
);

expect( ts.data ).toMatchSnapshot( );
} );

it( "and-type as empty interface with 2 heritage", ( ) =>
{
const ts = convertCoreTypesToTypeScript( wrapDocument( [
{
name: 'foo',
type: 'and',
and: [
{
type: 'object',
properties: { },
additionalProperties: false,
},
{
type: 'ref',
ref: 'bar',
},
{
type: 'ref',
ref: 'baz',
},
],
},
{
name: 'bar',
type: 'object',
properties: {
b: { required: true, node: { type: 'number' } },
},
additionalProperties: false,
},
{
name: 'baz',
type: 'object',
properties: {
z: { required: true, node: { type: 'boolean' } },
},
additionalProperties: false,
},
] ),
{ noDescriptiveHeader: true, noDisableLintHeader: true }
);

expect( ts.data ).toMatchSnapshot( );
} );

it( "and-type as non-empty interface with 1 heritage", ( ) =>
{
const ts = convertCoreTypesToTypeScript( wrapDocument( [
{
name: 'foo',
type: 'and',
and: [
{
type: 'object',
properties: {
f: { required: true, node: { type: 'string' } },
},
additionalProperties: false,
},
{
type: 'ref',
ref: 'bar',
},
],
},
{
name: 'bar',
type: 'object',
properties: {
b: { required: true, node: { type: 'number' } },
},
additionalProperties: false,
},
] ),
{ noDescriptiveHeader: true, noDisableLintHeader: true }
);

expect( ts.data ).toMatchSnapshot( );
} );

it( "and-type as non-empty interface with 2 heritage", ( ) =>
{
const ts = convertCoreTypesToTypeScript( wrapDocument( [
{
name: 'foo',
type: 'and',
and: [
{
type: 'object',
properties: {
f: { required: true, node: { type: 'string' } },
},
additionalProperties: false,
},
{
type: 'ref',
ref: 'bar',
},
{
type: 'ref',
ref: 'baz',
},
],
},
{
name: 'bar',
type: 'object',
properties: {
b: { required: true, node: { type: 'number' } },
},
additionalProperties: false,
},
{
name: 'baz',
type: 'object',
properties: {
z: { required: true, node: { type: 'boolean' } },
},
additionalProperties: false,
},
] ),
{ noDescriptiveHeader: true, noDisableLintHeader: true }
);

expect( ts.data ).toMatchSnapshot( );
} );
} );
Loading

0 comments on commit 4dc6953

Please sign in to comment.