diff --git a/src/NodeParser/TypeLiteralNodeParser.ts b/src/NodeParser/TypeLiteralNodeParser.ts index 571edd90b..ea49cc0c9 100644 --- a/src/NodeParser/TypeLiteralNodeParser.ts +++ b/src/NodeParser/TypeLiteralNodeParser.ts @@ -1,7 +1,8 @@ -import ts from "typescript"; +import ts, { isPropertySignature, MethodSignature, PropertySignature } from "typescript"; import { Context, NodeParser } from "../NodeParser"; import { SubNodeParser } from "../SubNodeParser"; import { BaseType } from "../Type/BaseType"; +import { FunctionType } from "../Type/FunctionType"; import { NeverType } from "../Type/NeverType"; import { ObjectProperty, ObjectType } from "../Type/ObjectType"; import { ReferenceType } from "../Type/ReferenceType"; @@ -38,13 +39,18 @@ export class TypeLiteralNodeParser implements SubNodeParser { let hasRequiredNever = false; const properties = node.members - .filter(ts.isPropertySignature) + .filter( + (element): element is PropertySignature | MethodSignature => + ts.isPropertySignature(element) || ts.isMethodSignature(element) + ) .filter((propertyNode) => !isNodeHidden(propertyNode)) .map( (propertyNode) => new ObjectProperty( this.getPropertyName(propertyNode.name), - this.childNodeParser.createType(propertyNode.type!, context), + isPropertySignature(propertyNode) + ? this.childNodeParser.createType(propertyNode.type!, context) + : new FunctionType(), !propertyNode.questionToken ) ) diff --git a/test/utils.ts b/test/utils.ts index 03ef5c963..04200688f 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -8,7 +8,9 @@ import { createFormatter } from "../factory/formatter"; import { createParser } from "../factory/parser"; import { createProgram } from "../factory/program"; import { Config } from "../src/Config"; +import { UnknownTypeError } from "../src/Error/UnknownTypeError"; import { SchemaGenerator } from "../src/SchemaGenerator"; +import { BaseType } from "../src/Type/BaseType"; const validator = new Ajv(); addFormats(validator); @@ -112,3 +114,13 @@ export function assertValidSchema( } }; } + +export function assertMissingFormatterFor(missingType: BaseType, relativePath: string, type?: string) { + return (): void => { + try { + assertValidSchema(relativePath, type)(); + } catch (error) { + expect(error).toEqual(new UnknownTypeError(missingType)); + } + }; +} diff --git a/test/valid-data-type.test.ts b/test/valid-data-type.test.ts index 406744a48..3c71b8fa2 100644 --- a/test/valid-data-type.test.ts +++ b/test/valid-data-type.test.ts @@ -1,4 +1,5 @@ -import { assertValidSchema } from "./utils"; +import { FunctionType } from "../src/Type/FunctionType"; +import { assertMissingFormatterFor, assertValidSchema } from "./utils"; describe("valid-data-type", () => { it("type-aliases-primitive", assertValidSchema("type-aliases-primitive", "MyString")); @@ -75,6 +76,10 @@ describe("valid-data-type", () => { it("type-indexed-access-object-1", assertValidSchema("type-indexed-access-object-1", "MyType")); it("type-indexed-access-object-2", assertValidSchema("type-indexed-access-object-2", "MyType")); it("type-indexed-access-keyof", assertValidSchema("type-indexed-access-keyof", "MyType")); + it( + "type-indexed-access-method-signature", + assertMissingFormatterFor(new FunctionType(), "type-indexed-access-method-signature", "MyType") + ); it("type-indexed-circular-access", assertValidSchema("type-indexed-circular-access", "*")); it("type-keyof-tuple", assertValidSchema("type-keyof-tuple", "MyType")); it("type-keyof-object", assertValidSchema("type-keyof-object", "MyType")); diff --git a/test/valid-data/type-indexed-access-method-signature/main.ts b/test/valid-data/type-indexed-access-method-signature/main.ts new file mode 100644 index 000000000..2816ef546 --- /dev/null +++ b/test/valid-data/type-indexed-access-method-signature/main.ts @@ -0,0 +1 @@ +export type MyType = { foo(): void }["foo"];