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
N.B. these notes use the word "module" extensively, which we now use to only mean "external module" in the old parlance. I will use "namespace" to refer to "internal modules" if needed.
Augmenting Types from External Modules (#5269, #4166)
Bind operator is like extension methods for JS
But people do love .
And if you love .., prototype mutation is the only way to accomplish it
Two problems facing Rx
How do I make a class appear to have methods that I don't want to implement
Remove the check for ambientness of classes merged with interfaces (:+1:)
How do I make the type of a global (or module-scoped) type depend on the set of modules that are imported?
This is an anti-pattern, but what can you do ¯_(ツ)_/¯
Some very terrible workarounds exist
Implementation approach
Binder has a concept of 'scripts' which contribute to the global, and 'modules' which contribute to their local scope, along with their separate exports
Only ambient modules have a symbol in the global scope, which is their quoted name
Module files never get a symbol and are not subject to merging; this is what we would need to change
Fix: add a canonical name to all module files so that they become mergable
This gets us augmentation of modules even from within other modules, which is currently disallowed
Q: How do you augment global types in this model?
A: We have a special string that means the global scope, use e.g. declare module '/' { or declare module '' {
Note that the types in a module would not directly visible in an interior ambient module declaration
Add an import declaration? It's weird. Maybe implicitly import them into scope... try it out and see what happens, should be OK
Q: How do we resolve these names?
A: Relative to the current file
Q: How do we produce these canonical names?
A: Need to figure that out. Doable.
Q: How do I refer to shadowed global types from within an ambient module inside a module?
A: Maybe you just don't... or refer to "./obs".Observable
A: Or `import { Observable } from './obs';
A: Or global.Array in the global case?
A: Or interface obs.Observable<T> { ... } <- nice
Theory that interface foo.bar { } always means extendingbar from the foo namespace
With special LHS semantics for global
Can I declare things here, too?
Yes
Syntax/semantics: interface global::Foo, interface global.Foo, interface global Foo, ?
declare global var x;
declare in './obs' var x;
What happens if I try to declare in a non-existent module?
It's like an ambient external module?
Only ambient classes could use dotted declarations
Speculation that we could emit non-ambient classes this way
👍 Conclusions
Allow merging of interfaces and non-ambient classes
declare module 'foo' { is allowed in modules
Are the containing module's symbols in scope? Yes, and the global symbols have priority
declare module '../relativePath' { is allowed in a module, but not in a script
Are the containing module's symbols in scope? Yes
declare global { augments the gloal scope, and is only allowed at top-level in a module (not a script)
Are module imports allowed in here? No.
Is export = allowed in here? No.
Are the containing module's symbols in scope? Yes
Rabble about declaration emitter
Vlad and Anders to tackle it
The text was updated successfully, but these errors were encountered:
N.B. these notes use the word "module" extensively, which we now use to only mean "external module" in the old parlance. I will use "namespace" to refer to "internal modules" if needed.
Augmenting Types from External Modules (#5269, #4166)
.
.
., prototype mutation is the only way to accomplish itdeclare module '/' {
ordeclare module '' {
import
declaration? It's weird. Maybe implicitly import them into scope... try it out and see what happens, should be OK"./obs".Observable
global.Array
in the global case?interface obs.Observable<T> { ... }
<- niceinterface foo.bar { }
always means extendingbar
from thefoo
namespaceglobal
interface global::Foo
,interface global.Foo
,interface global Foo
, ?declare global var x;
declare in './obs' var x;
declare in
a non-existent module?declare module 'foo' {
is allowed in modulesdeclare module '../relativePath' {
is allowed in a module, but not in a scriptdeclare global {
augments the gloal scope, and is only allowed at top-level in a module (not a script)import
s allowed in here? No.export =
allowed in here? No.The text was updated successfully, but these errors were encountered: