Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is the type of function generic type param #51447

Closed
zyf0330 opened this issue Nov 8, 2022 · 5 comments
Closed

What is the type of function generic type param #51447

zyf0330 opened this issue Nov 8, 2022 · 5 comments

Comments

@zyf0330
Copy link

zyf0330 commented Nov 8, 2022

Bug Report

I cannot figure out what is the type of generic T in the below playground code.
The generic T param which extends a class in the function, seems to be the never type, but I think it shouldn't be.

🔎 Search Terms

function generic type type param extends never

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about extends and generic

⏯ Playground Link

Playground link with relevant code

🙁 Actual behavior

The generic T seems to be never type.

🙂 Expected behavior

The generic T should be object or any type.

@MartinJohns
Copy link
Contributor

MartinJohns commented Nov 8, 2022

The type of T within test<>() is not known, because it's a generic type argument. Within the function the compiler does not know what type T is, so it can't resolve your conditional type TestT<T>. This is a design limitation.

The generic T seems to be never type.

It's not never, it's T. But what T is is not known.

@zyf0330
Copy link
Author

zyf0330 commented Nov 8, 2022

Actually, this is my actual type function which resolves key chain of type. And I don't know how to make it work for generic T.

export type NestedPaths<Type> =
// forbid access Function property
    Type extends Function ? never
        : Type extends string | number | boolean | Date | RegExp | Buffer | Uint8Array | {
            _bsontype: string;
        } ? [] : Type extends ReadonlyArray<infer EleType> ? ([ArrayIndexes<Type>, ...NestedPaths<EleType>] | [...NestedPaths<EleType>])
            : Type extends object ?
                (
                    {
                        [Key in Extract<keyof Type, string>]:
                        // forbid circular reference
                        (Type[Key] extends Type ? [Key] : Type extends Type[Key] ? [Key] : Type[Key] extends ReadonlyArray<infer EleType> ? Type extends EleType ? [Key] : EleType extends Type ? [Key]
                                : [Key, ...NestedPaths<Type[Key]>]
                            : [Key, ...NestedPaths<Type[Key]>]);
                    }[Extract<keyof Type, string>]
                    // allow to infer partial key chain, and ensure to infer the exact depth of key chain
                    | []
                    )
                : [];

@zyf0330
Copy link
Author

zyf0330 commented Nov 8, 2022

To simplify it, use this code to explain.

class ClassA {c?: string}
function test<T extends ClassA>() {
    const ks: T extends any ? keyof T : keyof T  = "c" // TS2322: Type '"c"' is not assignable to type 'T extends any ? keyof T :   keyof T'.
    const ks1: keyof T  = "c" // ok
    const ks2: ClassA extends any ? keyof T : keyof T  = "c" // ok
}

How to make ks work?

@MartinJohns
Copy link
Contributor

@zyf0330 You can't. The type of ks depends on the type T, but the type of T is not known within the function, because it's passed along from the outside.

@zyf0330
Copy link
Author

zyf0330 commented Nov 8, 2022

Thanks.
I just find a related issue #24560, so it seems that I cannot solve this problem.

@zyf0330 zyf0330 closed this as completed Nov 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants