From 28ba3497097f8935e5252c95377f273e512cd368 Mon Sep 17 00:00:00 2001 From: "Shlomi Assaf (shlassaf)" Date: Tue, 10 Oct 2017 04:50:02 +0300 Subject: [PATCH] add the TypeOperatorType that represents an operator result on a type ("keyof") --- examples/basic/src/classes.ts | 4 +- src/lib/converter/types/index.ts | 1 + src/lib/converter/types/type-operator.ts | 32 +++ src/lib/models/types/index.ts | 1 + src/lib/models/types/type-operator.ts | 67 ++++++ src/test/converter/type-operator/specs.json | 196 ++++++++++++++++++ .../converter/type-operator/type-operator.ts | 15 ++ .../specs/classes/_classes_.baseclass.html | 4 +- .../specs/classes/_classes_.genericclass.html | 2 +- .../classes/_classes_.internalclass.html | 12 +- .../classes/_classes_.nongenericclass.html | 2 +- .../specs/classes/_classes_.subclassa.html | 2 +- .../specs/classes/_classes_.subclassb.html | 2 +- ..._default_export_.defaultexportedclass.html | 2 +- .../interfaces/_classes_.inameinterface.html | 2 +- .../interfaces/_classes_.iprintinterface.html | 2 +- .../_classes_.iprintnameinterface.html | 2 +- .../renderer/specs/modules/_classes_.html | 4 +- 18 files changed, 336 insertions(+), 16 deletions(-) create mode 100644 src/lib/converter/types/type-operator.ts create mode 100644 src/lib/models/types/type-operator.ts create mode 100644 src/test/converter/type-operator/specs.json create mode 100644 src/test/converter/type-operator/type-operator.ts diff --git a/examples/basic/src/classes.ts b/examples/basic/src/classes.ts index f558b64ae..a8044e1f1 100644 --- a/examples/basic/src/classes.ts +++ b/examples/basic/src/classes.ts @@ -73,7 +73,7 @@ export class BaseClass implements INameInterface /** * This is an instance member of an internal class. */ - private internalClass:InternalClass; + private internalClass:InternalClass; constructor(name:string); @@ -181,7 +181,7 @@ export class BaseClass implements INameInterface /** * This is an internal class, it is not exported. */ -class InternalClass +class InternalClass { constructor(options:{name:string}) { diff --git a/src/lib/converter/types/index.ts b/src/lib/converter/types/index.ts index 5537ac987..599bede9c 100644 --- a/src/lib/converter/types/index.ts +++ b/src/lib/converter/types/index.ts @@ -9,5 +9,6 @@ export { ReferenceConverter } from './reference'; export { ThisConverter } from './this'; export { TupleConverter } from './tuple'; export { TypeParameterConverter } from './type-parameter'; +export { TypeOperatorConverter } from './type-operator'; export { UnionOrIntersectionConverter } from './union-or-intersection'; export { UnknownConverter } from './unknown'; diff --git a/src/lib/converter/types/type-operator.ts b/src/lib/converter/types/type-operator.ts new file mode 100644 index 000000000..fa9bac6da --- /dev/null +++ b/src/lib/converter/types/type-operator.ts @@ -0,0 +1,32 @@ +import * as ts from 'typescript'; + +import { TypeOperatorType } from '../../models/types/index'; +import { Component, ConverterTypeComponent, TypeNodeConverter } from '../components'; +import { Context } from '../context'; + +@Component({name: 'type:type-operator'}) +export class TypeOperatorConverter extends ConverterTypeComponent implements TypeNodeConverter { + /** + * we want to run before union + */ + priority = 50; + + /** + * Test whether this converter can handle the given TypeScript node. + */ + supportsNode(context: Context, node: ts.TypeOperatorNode, type: ts.Type): boolean { + return !!(node.kind === ts.SyntaxKind.TypeOperator); + } + + /** + * Interpret the given type operator node and convert it into a type representing keys of a type + * + * @param context The context object describing the current state the converter is in. + * @param node The type operator node representing keys of a type. + * @returns The type representing keys of a type. + */ + convertNode(context: Context, node: ts.TypeOperatorNode): TypeOperatorType { + const target = this.owner.convertType(context, node.type); + return new TypeOperatorType(target); + } +} diff --git a/src/lib/models/types/index.ts b/src/lib/models/types/index.ts index 875c0a88d..b8dccc31d 100644 --- a/src/lib/models/types/index.ts +++ b/src/lib/models/types/index.ts @@ -6,6 +6,7 @@ export { ReferenceType } from './reference'; export { ReflectionType } from './reflection'; export { StringLiteralType } from './string-literal'; export { TupleType } from './tuple'; +export { TypeOperatorType } from './type-operator'; export { TypeParameterType } from './type-parameter'; export { UnionType } from './union'; export { UnknownType } from './unknown'; diff --git a/src/lib/models/types/type-operator.ts b/src/lib/models/types/type-operator.ts new file mode 100644 index 000000000..03576b177 --- /dev/null +++ b/src/lib/models/types/type-operator.ts @@ -0,0 +1,67 @@ +import { Type } from './abstract'; + +/** + * Represents a type operator type. + * + * ~~~ + * class A {} + * class B {} + * ~~~ + */ +export class TypeOperatorType extends Type { + /** + * The type name identifier. + */ + readonly type: string = 'typeOperator'; + + target: Type; + + // currently, there is only one type operator, this is always "keyof" + // but, if more types will be added in the future we are ready. + operator: 'keyof' = 'keyof'; + + constructor(target: Type) { + super(); + this.target = target; + } + + /** + * Clone this type. + * + * @return A clone of this type. + */ + clone(): Type { + return new TypeOperatorType(this.target.clone()); + } + + /** + * Test whether this type equals the given type. + * + * @param type The type that should be checked for equality. + * @returns TRUE if the given type equals this type, FALSE otherwise. + */ + equals(type: TypeOperatorType): boolean { + if (!(type instanceof TypeOperatorType)) { + return false; + } + + return type.target.equals(this.target); + } + + /** + * Return a raw object representation of this type. + */ + toObject(): any { + const result: any = super.toObject(); + result.operator = this.operator; + result.target = this.target.toObject(); + return result; + } + + /** + * Return a string representation of this type. + */ + toString() { + return `keyof ${this.target.toString()}`; + } +} diff --git a/src/test/converter/type-operator/specs.json b/src/test/converter/type-operator/specs.json new file mode 100644 index 000000000..dd6f81c4a --- /dev/null +++ b/src/test/converter/type-operator/specs.json @@ -0,0 +1,196 @@ +{ + "id": 0, + "name": "typedoc", + "kind": 0, + "flags": {}, + "children": [ + { + "id": 1, + "name": "\"type-operator\"", + "kind": 1, + "kindString": "External module", + "flags": { + "isExported": true + }, + "originalName": "%BASE%/type-operator/type-operator.ts", + "children": [ + { + "id": 5, + "name": "GenericClass", + "kind": 128, + "kindString": "Class", + "flags": { + "isExported": true + }, + "typeParameter": [ + { + "id": 6, + "name": "T", + "kind": 131072, + "kindString": "Type parameter", + "flags": {}, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "reference", + "name": "TestClass" + } + } + } + ], + "children": [ + { + "id": 7, + "name": "c", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "type-operator.ts", + "line": 14, + "character": 5 + } + ], + "type": { + "type": "typeParameter", + "name": "T", + "constraint": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "reference", + "name": "TestClass" + } + } + } + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 7 + ] + } + ], + "sources": [ + { + "fileName": "type-operator.ts", + "line": 13, + "character": 25 + } + ] + }, + { + "id": 2, + "name": "TestClass", + "kind": 128, + "kindString": "Class", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "TestClass comment short text.", + "text": "TestClass comment text.\n", + "tags": [ + { + "tag": "see", + "text": "[[TestClass]] @ fixtures\n" + } + ] + }, + "children": [ + { + "id": 3, + "name": "a", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "type-operator.ts", + "line": 9, + "character": 5 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 4, + "name": "b", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "type-operator.ts", + "line": 10, + "character": 5 + } + ], + "type": { + "type": "intrinsic", + "name": "number" + } + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [ + 3, + 4 + ] + } + ], + "sources": [ + { + "fileName": "type-operator.ts", + "line": 8, + "character": 22 + } + ] + } + ], + "groups": [ + { + "title": "Classes", + "kind": 128, + "children": [ + 5, + 2 + ] + } + ], + "sources": [ + { + "fileName": "type-operator.ts", + "line": 1, + "character": 0 + } + ] + } + ], + "groups": [ + { + "title": "External modules", + "kind": 1, + "children": [ + 1 + ] + } + ] +} \ No newline at end of file diff --git a/src/test/converter/type-operator/type-operator.ts b/src/test/converter/type-operator/type-operator.ts new file mode 100644 index 000000000..3edd1f3ad --- /dev/null +++ b/src/test/converter/type-operator/type-operator.ts @@ -0,0 +1,15 @@ +/** + * TestClass comment short text. + * + * TestClass comment text. + * + * @see [[TestClass]] @ fixtures + */ +export class TestClass { + a: string; + b: number; +} + +export class GenericClass { + c: T; +} diff --git a/src/test/renderer/specs/classes/_classes_.baseclass.html b/src/test/renderer/specs/classes/_classes_.baseclass.html index ee426a3e9..43eb29796 100644 --- a/src/test/renderer/specs/classes/_classes_.baseclass.html +++ b/src/test/renderer/specs/classes/_classes_.baseclass.html @@ -180,7 +180,7 @@

Properties

Private internalClass

-
internalClass: InternalClass
+
internalClass: InternalClass<keyof BaseClass>
+
+

Type parameters

+
    +
  • +

    TTT: keyof BaseClass

    +
  • +
+

Hierarchy

    @@ -183,7 +191,7 @@

    Returns

    -
  • +
  • InternalClass
    • diff --git a/src/test/renderer/specs/classes/_classes_.nongenericclass.html b/src/test/renderer/specs/classes/_classes_.nongenericclass.html index 059dfb6cc..a0b3ecff1 100644 --- a/src/test/renderer/specs/classes/_classes_.nongenericclass.html +++ b/src/test/renderer/specs/classes/_classes_.nongenericclass.html @@ -352,7 +352,7 @@

      Returns void GenericClass

    • -
    • +
    • InternalClass
    diff --git a/src/test/renderer/specs/classes/_classes_.subclassa.html b/src/test/renderer/specs/classes/_classes_.subclassa.html index b8209c671..988811ad9 100644 --- a/src/test/renderer/specs/classes/_classes_.subclassa.html +++ b/src/test/renderer/specs/classes/_classes_.subclassa.html @@ -658,7 +658,7 @@

    Returns string GenericClass

  • -
  • +
  • InternalClass
  • diff --git a/src/test/renderer/specs/classes/_classes_.subclassb.html b/src/test/renderer/specs/classes/_classes_.subclassb.html index 3426354cf..03dd9633a 100644 --- a/src/test/renderer/specs/classes/_classes_.subclassb.html +++ b/src/test/renderer/specs/classes/_classes_.subclassb.html @@ -493,7 +493,7 @@

    Returns string GenericClass

  • -
  • +
  • InternalClass
  • diff --git a/src/test/renderer/specs/classes/_default_export_.defaultexportedclass.html b/src/test/renderer/specs/classes/_default_export_.defaultexportedclass.html index f48fa3d7b..692b7b667 100644 --- a/src/test/renderer/specs/classes/_default_export_.defaultexportedclass.html +++ b/src/test/renderer/specs/classes/_default_export_.defaultexportedclass.html @@ -74,7 +74,7 @@

    Class DefaultExportedClass

    This class is exported via es6 export syntax.

    -
    export default class DefaultExportedClass
    +					
    export default class DefaultExportedClass
     
diff --git a/src/test/renderer/specs/interfaces/_classes_.inameinterface.html b/src/test/renderer/specs/interfaces/_classes_.inameinterface.html index 395e1ff3e..f9f77bfae 100644 --- a/src/test/renderer/specs/interfaces/_classes_.inameinterface.html +++ b/src/test/renderer/specs/interfaces/_classes_.inameinterface.html @@ -214,7 +214,7 @@

Returns string GenericClass -
  • +
  • InternalClass
  • diff --git a/src/test/renderer/specs/interfaces/_classes_.iprintinterface.html b/src/test/renderer/specs/interfaces/_classes_.iprintinterface.html index 4a04c5054..06a0889e8 100644 --- a/src/test/renderer/specs/interfaces/_classes_.iprintinterface.html +++ b/src/test/renderer/specs/interfaces/_classes_.iprintinterface.html @@ -187,7 +187,7 @@

    Returns void GenericClass

  • -
  • +
  • InternalClass
  • diff --git a/src/test/renderer/specs/interfaces/_classes_.iprintnameinterface.html b/src/test/renderer/specs/interfaces/_classes_.iprintnameinterface.html index 88573f9dd..c2edcb34e 100644 --- a/src/test/renderer/specs/interfaces/_classes_.iprintnameinterface.html +++ b/src/test/renderer/specs/interfaces/_classes_.iprintnameinterface.html @@ -271,7 +271,7 @@

    Returns void GenericClass

  • -
  • +
  • InternalClass
  • diff --git a/src/test/renderer/specs/modules/_classes_.html b/src/test/renderer/specs/modules/_classes_.html index dbbf73946..445ff46a8 100644 --- a/src/test/renderer/specs/modules/_classes_.html +++ b/src/test/renderer/specs/modules/_classes_.html @@ -75,7 +75,7 @@

    Classes