Skip to content

Unresolved generic type arguments end up in type declarations since 5.7.2 #61338

Description

@AlCalzone

🔎 Search Terms

unresolved, undefined, declarations

🕗 Version & Regression Information

  • This changed between versions 5.6.3 and 5.7.2

In a project, I have a relatively complex set of generic types to be able to declare some values that get expanded and merged with defaults at runtime, while exposing that behavior in the type system. This seems to be complex enough that the semantic highlighting in VSCode regularly breaks in that file: https://github.com/zwave-js/zwave-js/blob/133172125d4148ea6e9e92a059b4325862ff6dd7/packages/cc/src/lib/Values.ts

Until TS 5.6.3, this code

exportconstBasicCCValues=Object.freeze({
...V.defineStaticCCValues(CommandClasses.Basic,{
...V.staticProperty("currentValue",{
...ValueMetadata.ReadOnlyLevel,label: "Current value"asconst,}),// ...});

would result in a type definition like this:

exportdeclareconstBasicCCValues: Readonly<{currentValue: {readonlyid: {commandClass: CommandClasses.Basic;property: "currentValue";};readonlyendpoint: (endpoint?: number|undefined)=>{readonlycommandClass: CommandClasses.Basic;readonlyendpoint: number;readonlyproperty: "currentValue";};readonlyis: (valueId: ValueID)=>boolean;readonlymeta: {readonlylabel: "Current value";readonlywriteable: false;readonlymax: 99;readonlymin: 0;readonlytype: "number";readonlyreadable: true;};readonlyoptions: {readonlyinternal: false;readonlyminVersion: 1;readonlysecret: false;readonlystateful: true;readonlysupportsEndpoints: true;readonlyautoCreate: true;};};}>;

Since 5.7.2, this is what gets generated. Note that ValueIDBase and TBlueprint are generics type arguments used in the transformation that aren't defined in the output file, so the entire types of the meta and options properties effectively resolve to any. It seems that somewhere along the line, TS just gives up resolving:

exportdeclareconstBasicCCValues: Readonly<{currentValue: {readonlyid: ValueIDBase;readonlyendpoint: (endpoint?: number|undefined)=>{readonlycommandClass: CommandClasses.Basic;readonlyendpoint: number;readonlyproperty: "currentValue";};readonlyis: (valueId: ValueID)=>boolean;readonlymeta: Readonly<(ValueMetadataextendsNonNullable<TBlueprint["meta"]> ? Readonly<{readonlytype: "any";readonlyreadable: true;readonlywriteable: true;}> : import("alcalzone-shared/types").Simplify<import("alcalzone-shared/types").Omit<Readonly<{readonlytype: "any";readonlyreadable: true;readonlywriteable: true;}>,("type"|"readable"|"writeable")&keyofNonNullable<TBlueprint["meta"]>>&TBlueprint["meta"]>)extends infer T ? {[KinkeyofTas[undefined]extends[(ValueMetadataextendsNonNullable<TBlueprint["meta"]> ? Readonly<{readonlytype: "any";readonlyreadable: true;readonlywriteable: true;}> : import("alcalzone-shared/types").Simplify<import("alcalzone-shared/types").Omit<Readonly<{readonlytype: "any";readonlyreadable: true;readonlywriteable: true;}>,("type"|"readable"|"writeable")&keyofNonNullable<TBlueprint["meta"]>>&TBlueprint["meta"]>)[K]] ? never : K]: (ValueMetadataextendsNonNullable<TBlueprint["meta"]> ? Readonly<{readonlytype: "any";readonlyreadable: true;readonlywriteable: true;}> : import("alcalzone-shared/types").Simplify<import("alcalzone-shared/types").Omit<Readonly<{readonlytype: "any";readonlyreadable: true;readonlywriteable: true;}>,("type"|"readable"|"writeable")&keyofNonNullable<TBlueprint["meta"]>>&TBlueprint["meta"]>)[K];} : never>;readonlyoptions: Readonly<(import("@zwave-js/cc").CCValueOptionsextendsNonNullable<TBlueprint["options"]> ? {readonlyinternal: false;readonlyminVersion: 1;readonlysecret: false;readonlystateful: true;readonlysupportsEndpoints: true;readonlyautoCreate: true;} : import("alcalzone-shared/types").Simplify<import("alcalzone-shared/types").Omit<{readonlyinternal: false;readonlyminVersion: 1;readonlysecret: false;readonlystateful: true;readonlysupportsEndpoints: true;readonlyautoCreate: true;},("stateful"|"secret"|"internal"|"minVersion"|"supportsEndpoints"|"autoCreate")&keyofNonNullable<TBlueprint["options"]>>&TBlueprint["options"]>)extends infer T ? {[KinkeyofTas[undefined]extends[(import("@zwave-js/cc").CCValueOptionsextendsNonNullable<TBlueprint["options"]> ? {readonlyinternal: false;readonlyminVersion: 1;readonlysecret: false;readonlystateful: true;readonlysupportsEndpoints: true;readonlyautoCreate: true;} : import("alcalzone-shared/types").Simplify<import("alcalzone-shared/types").Omit<{readonlyinternal: false;readonlyminVersion: 1;readonlysecret: false;readonlystateful: true;readonlysupportsEndpoints: true;readonlyautoCreate: true;},("stateful"|"secret"|"internal"|"minVersion"|"supportsEndpoints"|"autoCreate")&keyofNonNullable<TBlueprint["options"]>>&TBlueprint["options"]>)[K]] ? never : K]: (import("@zwave-js/cc").CCValueOptionsextendsNonNullable<TBlueprint["options"]> ? {readonlyinternal: false;readonlyminVersion: 1;readonlysecret: false;readonlystateful: true;readonlysupportsEndpoints: true;readonlyautoCreate: true;} : import("alcalzone-shared/types").Simplify<import("alcalzone-shared/types").Omit<{readonlyinternal: false;readonlyminVersion: 1;readonlysecret: false;readonlystateful: true;readonlysupportsEndpoints: true;readonlyautoCreate: true;},("stateful"|"secret"|"internal"|"minVersion"|"supportsEndpoints"|"autoCreate")&keyofNonNullable<TBlueprint["options"]>>&TBlueprint["options"]>)[K];} : never>;};}>;

⏯ Playground Link

No response

💻 Code

No response

🙁 Actual behavior

see above

🙂 Expected behavior

see above

Additional information about the issue

I found another issue that might be related, but I'm not familiar enough with the details to know:
#60864

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions