Class DeclarationTransformer

Read the TypeScript AST and generate pack struct (instructions + pre-defined stack).

This transformer extracts type and add the encoded (so its small and low overhead) at classes and functions as property.

Deepkit/type can then extract and decode them on-demand.

Hierarchy

Constructors

Properties

addExports: {
    identifier: string;
}[] = []
addImports: {
    from: Expression;
    identifier: Identifier;
}[] = []
compileDeclarations: Map<InterfaceDeclaration | TypeAliasDeclaration | EnumDeclaration, {
    compiled?: Statement[];
    name: EntityName;
    sourceFile: SourceFile;
}> = ...

Types added to this map will get a type program directly under it. This is for types used in the very same file.

compiledDeclarations: Set<Node> = ...

When a node was embedded or compiled (from the maps above), we store it here to know to not add it again.

context: TransformationContext
currentReflectionConfig: ReflectionConfig = ...
defaultExcluded: string[] = ...
embedAssignType: boolean = false
embedDeclarations: Map<Node, {
    name: EntityName;
    sourceFile: SourceFile;
}> = ...

Types added to this map will get a type program at the top root level of the program. This is for imported types, which need to be inlined into the current file, as we do not emit type imports (TS will omit them).

f: NodeFactory
globalSourceFiles?: SourceFile[]
host: CompilerHost
knownClasses: {
    [name: string]: ReflectionOp;
} = ...

Type declaration

  • [name: string]: ReflectionOp
nodeConverter: NodeConverter
reflectionMode?: "default" | "always" | "never"
reflectionOptions?: ReflectionOptions
resolvedPackageJson: {
    [path: string]: {
        data: Record<string, any>;
        exists: boolean;
    };
} = {}

Type declaration

  • [path: string]: {
        data: Record<string, any>;
        exists: boolean;
    }
    • data: Record<string, any>
    • exists: boolean
resolvedTsConfig: {
    [path: string]: {
        data: Record<string, any>;
        exists: boolean;
    };
} = {}

Type declaration

  • [path: string]: {
        data: Record<string, any>;
        exists: boolean;
    }
    • data: Record<string, any>
    • exists: boolean
resolver: Resolver
sourceFile: SourceFile
tempResultIdentifier?: Identifier

When an deep call expression was found a script-wide variable is necessary as temporary storage.

typeChecker?: TypeChecker

Methods

  • A class is decorated with type information by adding a static variable.

    class Model { static __types = pack(ReflectionOp.string); //<-- encoded type information title: string; }

    Parameters

    • node: ClassDeclaration | ClassExpression

    Returns Node

  • With this function we want to check if type is used in the signature itself from the parent of declaration. If so, we do not try to infer the type from runtime values.

    Examples where we do not infer from runtime, type being T and declaration being <T> (return false):

    class User<T> {
    config: T;
    }

    class User<T> {
    constructor(public config: T) {}
    }

    function do<T>(item: T): void {}
    function do<T>(item: T): T {}

    Examples where we infer from runtime (return true):

    function do<T>(item: T) {
    return typeOf<T>; //<-- because of that
    }

    function do<T>(item: T) {
    class A {
    config: T; //<-- because of that
    }
    return A;
    }

    function do<T>(item: T) {
    class A {
    doIt() {
    class B {
    config: T; //<-- because of that
    }
    return B;
    }
    }
    return A;
    }

    function do<T>(item: T) {
    class A {
    doIt(): T { //<-- because of that
    }
    }
    return A;
    }

    Parameters

    • declaration: TypeParameterDeclaration
    • type: TypeReferenceNode | ExpressionWithTypeArguments

    Returns boolean

  • This is a custom resolver based on populated locals from the binder. It uses a custom resolution algorithm since we have no access to the binder/TypeChecker directly and instantiating a TypeChecker per file/transformer is incredible slow.

    Parameters

    • typeName: EntityName

    Returns void | {
        declaration: Node;
        importDeclaration?: ImportDeclaration;
        typeOnly?: boolean;
    }

  • Note: We have to duplicate the expressions as it can be that incoming expression are from another file and contain wrong pos/end properties, so the code generation is then broken when we simply reuse them. Wrong code like User.__type = [.toEqual({ is then generated. This function is probably not complete, but we add new copies when required.

    Parameters

    • value: undefined | PackExpression | PackExpression[]

    Returns Expression

Generated using TypeDoc