You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: Can not reuse declaration expressions? #12413
Inline named declaration expressions such as enum Type { ... } do not currently introduce a reusable binding in the surrounding model or namespace. Supporting references to those names is already tracked as a language/compiler design request.
Category: Feature Request Area: compiler:core
🔁 Possible duplicate of #189 — that issue tracks expression forms for declarations, including named inline enums/models and the question of whether and how those names can be referenced.
🔍 Analysis
The diagnostic is produced by compiler name resolution: the inline enum is a type expression, and its displayed name does not create a symbol named Type that sibling properties or Bar can resolve. This is the same underlying language-design gap described in #189 rather than an emitter-specific failure.
yeah we did discuss the scope of named expression and think it would create a much larger problem we they were hoisted to the namespace scope.
I guess we could consider introducing those direct parent scope but that is a whole new independent feature. (Like you can't reference another property without using the model name right now)
it isn't this would be the first mention of it, I was more explaining from a compiler behavior point of view.
I don't expect this to be added soon though, feel free to share more use case
First of all I would like to control what hoisted (i call it "materialized") at what name, to control the form it gets in openapi.
Example:
// burden library portionaliasGuessCreateModel<TextendsModel> =someFunctionOrStandardType(T);
aliasGuessCreatedModel<TextendsModel> =someFunctionOrStandardType(T);
interfaceCRUD<
TextendsModel,
CreateextendsModel = HOIST(GuessCreateModel<T>, "{name}Create"), // FIXME: this would become a hoisted model, truly named component in openapi
Created =HOIST(GuessCreatedModel<T>, "{name}Created"), // FIXME: this would become a hoisted model, truly named component in openapi
> {
opcreate(
@HOIST() @bodyRootinput:Create// FIXME: operation parameters would become a hoisted model `FooCreateInput`, truly named component in openapi, ref-ing FooCreate
):Created | ...; // FIXME: operation return would become a hoisted model `FooCreateOutput`, truly named component in openapi, ref-ing FooCreated
}
// clean mainmodelFoo { id:string, name:string }
interfaceFoosextendsCRUD<Foo> {}
In other words, I would like to offload the routine portion of defining a lengthy CRUD-like API to helper functions.
If it can not be done I would like to have kinda what other languages call macros -- again, to replace the repeatable parts of code with their expanded form -- the result of expansion should be both semantically and syntactically the same as one written by hands.
Example:
// burden library portion
macro DefineCRUD<T, CreateError = never> {
model ${T::name}Create { ...someFunctionOrStandardType(T) }
model ${T::name}Created { ...someFunctionOrStandardType(T) }
model ${T::name}CreateInput {
@bodyRoot input: ${T::name}Create,
}
union ${T::name}Output { model ${T::name}Created, CreateError }
interfaceIFoos {
opcreate(...${T::name}CreateInput): ${T::name}Output;
}
}
// clean mainmodelFoo { id:string, name:string }
expand(DefineCRUD<Foo>);
interfaceFoosextendsIFoos {}
Activity
github-actions commentedon Oct 28, 2026
🎯 Issue Triage
Inline named declaration expressions such as
enum Type { ... }do not currently introduce a reusable binding in the surrounding model or namespace. Supporting references to those names is already tracked as a language/compiler design request.Category: Feature Request
Area:
compiler:core🔁 Possible duplicate of #189 — that issue tracks expression forms for declarations, including named inline enums/models and the question of whether and how those names can be referenced.
🔍 Analysis
The diagnostic is produced by compiler name resolution: the inline enum is a type expression, and its displayed name does not create a symbol named
Typethat sibling properties orBarcan resolve. This is the same underlying language-design gap described in #189 rather than an emitter-specific failure.📝 Suggested next steps
enum Typeat namespace scope and reference it from both models.timotheeguerin commentedon Oct 28, 2026
yeah we did discuss the scope of named expression and think it would create a much larger problem we they were hoisted to the namespace scope.
I guess we could consider introducing those direct parent scope but that is a whole new independent feature. (Like you can't reference another property without using the model name right now)
dvv commentedon Oct 28, 2026
Aha, I see. Thank you for clarification.
Is that new feature planned short/middle-time?
timotheeguerin commentedon Oct 28, 2026
it isn't this would be the first mention of it, I was more explaining from a compiler behavior point of view.
I don't expect this to be added soon though, feel free to share more use case
dvv commentedon Oct 28, 2026
First of all I would like to control what hoisted (i call it "materialized") at what name, to control the form it gets in openapi.
Example:
In other words, I would like to offload the routine portion of defining a lengthy CRUD-like API to helper functions.
If it can not be done I would like to have kinda what other languages call macros -- again, to replace the repeatable parts of code with their expanded form -- the result of expansion should be both semantically and syntactically the same as one written by hands.
Example: