Open trusktr opened 8 months ago
I don’t think that counts as a declaration merge, it’s just “declaring a type and a value with the same name”. There’s no requirement that the two Foo
s be related as they exist in separate namespaces within the compiler. Declaration merge is when e.g. you declare an interface more than once and the second one augments the first.
Maybe its named something else. If so, what is this pattern named where a single identifier carries both a type and a value? I could not find anything about it in the TS docs (maybe I don't know what to search for).
From my perspective, I thought it was one (of multiple) forms of "declaration merging" because two things are being merged: a variable declaration, and a type declaration. I however did not see this on the Declaration Merging page in the docs.
Maybe the syntax needs to be
/**
* @export
* @typedef {InstanceType<typeof Foo>} Foo
*/
Ah, @Gerrit0 pointed out that the following works because typedef
is automatically exported:
export const Foo = makeFooClass() // returns a class
/** @typedef {InstanceType<typeof Foo>} Foo */
I do not see that this type exports feature is mentioned here:
https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html
Perhaps we need to add more info to that page.
If so, what is this pattern named where a single identifier carries both a type and a value? I could not find anything about it in the TS docs
I don't think there's a name for it because it's just declaring two different things that happen to have the same name, but the compiler considers them separate entities as one exists in type-space and the other in value-space[^1]. Nothing is really being merged.
[^1]: This split between type-space and value-space is why the typeof
operator exists. There's no requirement that Foo
and typeof Foo
be related, it's just in practice they usually are.
one exists in type-space and the other in value-space1. Nothing is really being merged.
They're being "merged" in the sense that the end user who will import the type can reference it with a single identifier, and to them it is the "one and same thing".
import {Foo} from './Foo.js'
const f = new Foo() // uses *both* Foos, which to the user is a single thing.
Maybe it can be called type value merging or something, but it definitely is some type of a merge (yeah, not merging of two interfaces)
🔍 Search Terms
jsdoc declaration merging
✅ Viability Checklist
⭐ Suggestion
Ability to merge declarations.
📃 Motivating Example
For example, this is a declaration merge in TS:
In JS we can't do this. I was hoping for something similar to this to achieve the same:
💻 Use Cases