microsoft / microsoft/TypeScript
Treat certain kinds of UMD initialization as a module in checkJS mode
Nessuno ha ancora preso questa issue.
- Lingua principale
- Go
- Stelle
- 111k
- Fork
- 14.3k
- Merge medio
- 1g 19h
- PR unite (30g)
- 117
Descrizione
Bug Report
Here's plain JavaScript that works in Node, all Browsers for the last 3+ years, and all Bundlers (Vite, WebPack, etc) without the absolute minimum possible boilerplate, but tsc can't make heads or tails of it.
foo.js:
var Foo = ("object" === typeof module && exports) || {};
(function (window) {
"use strict";
let Crypto = window.crypto || require("node:crypto");
Foo.secret = new Uint8Array(16);
Crypto.getRandomValues(Foo.secret);
/**
* @param {String} name
*/
Foo.greet = function (name) {
console.log(`Hello, ${name}!`);
};
//...
console.log(Crypto.getRandomValues);
})(globalThis.window || {});
uses-foo.js:
"use strict";
let Foo = require("./foo.js");
// This SHOULD have an error (but it doesn't)
// (meaning that Foo became global, but shouldn't have)
/** @type {Foo} */
let fooFail = null;
console.log(fooFail);
// This should NOT have an error (but it does)
// - Foo should be module-exported,
// - Foo.greet should automatically typed by its explicit definition
/** @type {import('./foo').Foo} */
let greet = Foo.greet;
greet("AJ");
jsconfig.json:
{
"compilerOptions": {
"target": "es2022",
"moduleDetection": "force",
"module": "commonjs",
"moduleResolution": "node",
"typeRoots": ["./typings", "./node_modules/@types"],
"allowJs": true,
"checkJs": true,
"noEmit": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitAny": true,
"alwaysStrict": true,
"skipLibCheck": true
},
"include": ["*.js", "bin/**/*.js", "lib/**/*.js", "src/**/*.js"],
"exclude": ["node_modules"]
}
🔎 Search Terms
- umd
🕗 Version & Regression Information
Always
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about umd
⏯ Playground Link
I couldn't figure out how to put multiple files in the playground or how to set the jsconfig.json, but here's the link anyway:
💻 Code
- https://github.com/coolaj86/example-jswt-umd/tree/main/umd-ideal-but-broken
- https://github.com/coolaj86/example-jswt-umd/tree/main/umd-ugly-but-works
Here's the super hack workaround:
/**
* @typedef Foo2
* @prop {Greet2} greet
* @prop {Uint8Array} secret
*/
/**
* @callback Greet2
* @param {String} name
*/
/** @type {Foo2} */
//@ts-ignore
var Foo2 = ("object" === typeof module && exports) || {};
(function (window, Foo2) {
"use strict";
let Crypto = window.crypto || require("node:crypto");
Foo2.secret = new Uint8Array(16);
Crypto.getRandomValues(Foo2.secret);
/**
* @param {String} name
*/
Foo2.greet = function (name) {
console.log(`Hello, ${name}!`);
};
return Foo2;
})(globalThis.window || {}, Foo2);
if ("object" === typeof module) {
module.exports = Foo2;
}
Issues with the hacky workaround are:
- looks really ugly and confusing, but triggers all the right heuristics in however
tscis doing its thing
🙁 Actual behavior
Can't detect any of Foo's properties, exports Foo as a global rather that a script, doesn't export the exports at all.
🙂 Expected behavior
All type info should be module style (not global script style) and should know that Foo is module.exports and that anything assigned to Foo is exported.
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Riproduci il comportamento nelle directory umd-ideal-but-broken e umd-ugly-but-works, iniziando da foo.js, uses-foo.js e jsconfig.json. Confronta l’esempio che non funziona con la soluzione alternativa, quindi verifica che checkJs tratti l’inizializzazione UMD supportata come un’inizializzazione in stile modulo, riconosca module.exports e gestisca le annotazioni di tipo Foo come previsto.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- javascript, typescript
- Ambito
- compilers
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 35/100