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

When class declared and returned in the function, .d.ts declaration does not meet the expectations #50492

Closed
shulandmimi opened this issue Aug 28, 2022 · 3 comments
Labels
Duplicate An existing issue was already created

Comments

@shulandmimi
Copy link

Bug Report

🔎 Search Terms

When class declared and returned in the function, .d.ts declaration does not meet the expectations

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about declaration and class method

⏯ Playground Link

Playground link with relevant code

💻 Code

// const Foo = (function() {
//     return class Foo {
//         name: string = 'shulandmimi';

//         extend(): Foo {
//             return new Foo();
//         }
//     }
// })();

// or

const Foo = class Foo {
    name: string = 'shulandmimi';

    extend(): Foo {
        return new Foo();
    }
};

const foo_instance = new Foo();

// in playground: (method) Foo.extend(): Foo; foo1: Foo;
// in .d.ts: (method) Foo.extend(): any; foo1: any

const foo1 = foo_instance.extend(); 

🙁 Actual behavior

declare const Foo: {
    new (): {
        name: string;
        extend(): any;
    };
};
declare const foo_instance: {
    name: string;
    extend(): any;
};
declare const foo1: {
    name: string;
    extend(): any;
};

🙂 Expected behavior

declare const Foo: {
    new (): {
        name: string;
        extend(): Foo;
    };
};
declare const foo_instance: {
    name: string;
    extend(): Foo;
};
declare const foo1: {
    name: string;
    extend(): Foo;
};
@jcalz
Copy link
Contributor

jcalz commented Aug 28, 2022

Your expected behavior has errors; there is no type named Foo:

declare const Foo: {
    new (): {
        name: string;
        extend(): Foo; // error!
    };
};
declare const foo_instance: {
    name: string;
    extend(): Foo; // error!
};
declare const foo1: {
    name: string;
    extend(): Foo; // error!
};

Playground link

Presumably you'd actually want to see something like #463 or #44045 where the currently anonymous type you're calling Foo would be named and exported as well. Until or unless that happens you need to do it yourself:

interface Foo {
    name: string;
    extend(): Foo;
}

const Foo = class {
    name: string = 'shulandmimi';

    extend(): Foo {
        return new Foo();
    }
};

const foo_instance = new Foo();
const foo1 = foo_instance.extend(); 

Playground link

@shulandmimi
Copy link
Author

Presumably you'd actually want to see something like #463 or #44045 where the currently anonymous type you're calling Foo would be named and exported as well. Until or unless that happens you need to do it yourself:

interface Foo {
    name: string;
    extend(): Foo;
}

const Foo = class {
    name: string = 'shulandmimi';

    extend(): Foo {
        return new Foo();
    }
};

const foo_instance = new Foo();
const foo1 = foo_instance.extend(); 

thanks for your reply, the solution you proposed did work for me, but I still have some questions

const FooClass = class Foo { ... } is actually const FooClass: typeof class Foo { ... }

It doesn't seem to conform to #463 circular reference to itself

When a class is declared and returned in a function, there are two cases

// 1
function createFoo() {
     class Foo {
         extend(): Foo {
             return new Foo();
         }
     }
     return Foo;
}

// 2
function createFoo() {
     return class Foo {
         extend(): Foo {
             return new Foo();
         }
     }
}

In the playground, 1 will throw a reference to a private type error, while 2 will generate a type from typeof Foo and run without error

But in the second case, during the generation of .d.ts, Foo will be replaced by typeof Foo, and Foo will be discarded, causing the extend method to return any

Should this be the case instead of the current solution

  1. Should the second case be the same as the first
  2. The second case should be consistent with the runtime

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Aug 29, 2022
@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants