ES Modules in Node
https://gist.github.com/weswigham/22a064ffa961d5921077132ae2f8da78
-
export maps and .d.ts files
-
The same way we let you file a types field to reflect the main, we should have a "types" condition in your export maps.
{
"exports": {
"./": {
"import+types": "./ts/esm/index.d.ts", // <- this reflects the types you get for an import
"require+types": "./ts/cjs/index.d.ts", // <- this reflects the type you get for a require()
"import": "./esm/index.js",
"require": "./cjs/index.js",
}
}
}
-
Alternatively, "nested conditions" approach
{
"exports": {
"./": {
"types": {
"import": "./ts/esm/index.d.ts", // <- this reflects the types you get for an import
"require": "./ts/cjs/index.d.ts", // <- this reflects the type you get for a require()
},
"import": "./esm/index.js",
"require": "./cjs/index.js",
}
}
}
-
typesVersions?
-
Do we expect these exports to be written by hand?
-
This is all quite a lot of complexity.
- Most people won't need multiple entry points and the like.
-
typesVersions was explicit, this isn't.
-
It's not necessarily just about ESM imports vs CJS require.
- It's also about Node vs. the browser.
- Also maybe about ES5 vs ESNext
- There's value in the fact that you can nest these in flexible ways.
import+types>4.4 seems a little bit confusing, maybe "abusive" of the export map syntax.
- Spec kind of expected identifier-like strings.
- This behavior is relied on specially - for example, anything starting with a
. is a path, anything not is "special".
- Make sure people involved in Node take a look.
- (side note: be cognicent of people importing
.d.ts files like assets?)
-
Seems like team slightly prefers nesting, not concatenating (e.g. yadda+types)
{
"exports": {
"./": {
"types": {
"import": "./ts/esm/index.d.ts",
"require": "./ts/cjs/index.d.ts",
},
"import": "./esm/index.js",
"require": "./cjs/index.js",
}
}
}
- But still need to check how that works for versioning.
- Versioning?
-
typescript@>=4.4
-
types>=4.4
-
What about
{
"exports": {
"./": {
"types": {
"import": "./ts/esm/index.d.ts",
"require": "./ts/cjs/index.d.ts",
},
"typesVersions": {
">=4.4": "..."
},
"import": "./esm/index.js",
"require": "./cjs/index.js",
}
}
}
- Doesn't make sense because there's multiple ways to specify versioning in this manner.
- If you care about versions older than whatever TypeScript supports this, you'll still need a top-level
typesVersion.
- Can't omit support for
typesVersions from the MVP, otherwise users have to specially support the MVP in a weird way.
- Leaning towards
{
"exports": {
"./": {
"types": {
"import": "./ts/esm/index.d.ts",
"require": "./ts/cjs/index.d.ts",
},
"types<=4.5": {
"import": "./ts/esm/index.d.ts",
"require": "./ts/cjs/index.d.ts",
},
"import": "./esm/index.js",
"require": "./cjs/index.js",
}
}
}
"types<=4.5" or "types@<=4.5"?
types@* vs types*?
- You'd just write
types.
- But it's usually a semver pattern.
- Need something that separates the semver pattern.
Breaking Changes
#44093
#44092
- Change in inference.
- We'll look into this.
#44087
- Issue is that we look for all things that
number is assignable to, reduce everything.
- In theory, should reject the assignment.
- So inclined to say "won't fix" - weirdness is caused by a bad assignment.
#43877
- Bloomberg found the cause internally.
- Without a minimal repro, can't improve anything.
unknown in catch
#41016
#41013
- People liked
unknown in a survey.
- But it sucks to turn on in the TypeScript codebase.
- What do you mean by it "sucks in the TS codebase?"
- Lots of well-working code that doesn't improve.
- "I'm willing to do the feature, I'm not willing to be the one who converts the TypeScript codebase to use it."
- Like all good strictness flags.
- Seems wrong that we don't complain about that loose
any under strict.
- Can always do a refactoring to migrate an existing codebase to use
: any in catch clauses.
- That helps us feel okay with putting this under
--strict.
- Would be great to have a way to say "the only thing this throws is
Error".
- Agreed, but no way to do that today.
- Could totally imagine a thing that asserts the type of the error thrown.
- Seems like we're okay with this flag going under
--strict.
ES Modules in Node
https://gist.github.com/weswigham/22a064ffa961d5921077132ae2f8da78
exportmaps and.d.tsfilesThe same way we let you file a
typesfield to reflect themain, we should have a "types" condition in your export maps.Alternatively, "nested conditions" approach
typesVersions?Version specifier in the
exportsmap?Do we expect these
exportsto be written by hand?This is all quite a lot of complexity.
typesVersionswas explicit, this isn't.It's not necessarily just about ESM imports vs CJS require.
import+types>4.4seems a little bit confusing, maybe "abusive" of the export map syntax..is a path, anything not is "special"..d.tsfiles like assets?)Seems like team slightly prefers nesting, not concatenating (e.g.
yadda+types)typescript@>=4.4types>=4.4What about
typesVersion.typesVersionsfrom the MVP, otherwise users have to specially support the MVP in a weird way."types<=4.5"or"types@<=4.5"?types@*vstypes*?types.Breaking Changes
#44093
#44092
#44087
numberis assignable to, reduce everything.#43877
unknownincatch#41016
#41013
unknownin a survey.anyunderstrict.: anyincatchclauses.--strict.Error".--strict.