-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Proposal: Allow isolated declarations to infer results of constructor calls #60010
Comments
This probably isn't possible as the constuctor for types don't have to have any relation to the returned type. i.e. If you have Like the following example couldn't work with // lib.ts
export type Bar = {
prop: number;
};
export type FooConstructor = new () => Bar;
export const Foo: FooConstructor = function() { /* ... */ };
// main.ts
import { Foo } from "./lib.ts";
const f = new Foo(); |
My proposal already covers this:
Since there is no type |
It's worth noting that it's possible to get the type via For example: const x = new Map<string, number>();
(x satisfies InstanceType<typeof Map<string, number>>) There may be some edge cases but this could be the mechanical transform that allows the general case to work. |
This was discussed in our initial ID meetings but a fully-correct implementation is quite fraught. The real check you have to do is pretend that a // joker.ts
export type Bar = {
a: string;
}
export type Foo = Bar;
export const Foo = {
new(): Foo;
} where import { Foo, Bar } from "./joker.js"
const f = new Foo(); where at const f: Foo
While it's true that |
The design we settled on for isolatedDeclarations to start was that any error checking must not consult the checker, such that an external emitter could know when an annotation is needed/not needed without tsc. Anything past that are "optimistic" checks where one would need to call tsc somewhere to know that the output is usable (along with defining new rules that say stuff like " But the lack of inference on |
I wrote the above on my phone and the page didn't update with Ryan's comment until I sent it, oops |
Does it need to be that strict? Could we settle for checking assignability? Like treat it as semantically equivalent to
I think that's exactly right and I think having optimistic checks brings some needed ergonomics to using isolated declarations. I think #58800 is in the same boat (please prioritize that one over this though I'd hope both make it into 5.7). |
You're talking about a different feature than |
@RyanCavanaugh wouldn't your tricky case be handled by Would there be some pure syntax transform that could be done like that? Are there edge cases that it couldn't handle? |
Unfortunately overloads don't really work with conditional types so a simple case like: type C = {
new(): Foo1;
new(x: number): Foo2;
};
// The type here is always Foo2
const o: InstanceoOf<C> = new C(); If the overload-conditional types interation though could be fixed, then having a transform like would work: type InstanceOf<Args extends ReadonlyArray<any>, C extends new(...args: Args) => any>
= C extends new(...args: Args) => infer R ? R : never;
const o1: InstanceOf<[], C> = new C();
const o2: InstanceOf<[number], C> = new C(3); but this would require all parameters to be suitable for inference within isolated declarations. |
π Search Terms
isolated declarations constructor generic infer
β Viability Checklist
β Suggestion
Add a new flag or change the behavior of
--isolatedDeclarations
so that in the following code which is currently disallowed by isolated declarations:if the type of
foo
is notFoo
, there is a typecheck error. In return, the type offoo
will be emitted asFoo
.Similarly, if somehow in
foo
is not aFoo<A>
, there is a typecheck error.π Motivating Example
Currently under isolated declarations, code must redundantly declare the type of a variable which is the result of a constructor call.
This setting would also eliminate #59768
π» Use Cases
^
The text was updated successfully, but these errors were encountered: