deepkit / deepkit-framework

A new full-featured and high-performance TypeScript framework
https://deepkit.io/
MIT License
3.24k stars 124 forks source link

Reflection in Class<T> constructor fails (with never) if the class is instantiated via import #618

Closed Coderah closed 2 weeks ago

Coderah commented 2 weeks ago

Example is here https://codesandbox.io/p/devbox/deepkit-runtime-types-forked-89t3pr

The goal is to be able to extract the property names from the class generic type ComponentTypes I'm not positive if there is another approach here that would work?

Error for clarity: Error: TypeClass or TypeObjectLiteral expected, not never

marcj commented 2 weeks ago

Two issues here:

First: update deepkit to newest versions, deepkit/core, deepkit/type, and deepkit/type-compiler.

Next, it's not possible to access generic type arguments like that. A generic type in TS can be instantiated arbitrarily without runtime overhead. Deepkit does not hook into all generic expressions (for performance reasons) and thus makes it necessary to explicitly read a generic by using ReceiveType. The receiving side marks itself in a way that Deepkit understands it so that it can emit additional runtime code for each calling-side to actually pass the generic in runtime. See https://deepkit.io/documentation/runtime-types/reflection#receive-type-information

This works for functions and limited for classes. In your case you have to write Manager this way:

import { ReceiveType, ReflectionClass, resolveReceiveType } from '@deepkit/type';

export type defaultComponentTypes = {
    ownerId: string;
    updatedAt: number;
    createdAt: number;
};

export class Manager<ComponentTypes extends defaultComponentTypes> {
    constructor(type?: ReceiveType<ComponentTypes>) {
        type = resolveReceiveType(type);
        console.log(type);

        const reflection = ReflectionClass.from(type);
        console.log(
            'componentNames',
            reflection.getProperties().map((p) => p.name),
        );
    }
}
Coderah commented 2 weeks ago

Amazing! Thank you for the insight, this makes sense I just need to familiarize myself with more of deepkits reflection features.

👍