Specifying lib: DOM and WebWorker should not be mutually exclusive #20595
Comments
Not 100% sure, but I think you can just use DOM and drop WebWorker if you need both. WebWorker is probably for when you want access to WebWorker functionality but want to make sure you are not using anything else you would have with DOM. |
Unfortunately the base APIs for WebWorker and DOM are actually meaningfully different, and it's not clear at this point how to write a clean separation of global scopes between different parts of your project other than splitting your project into multiple parts. |
We have found that what is meaningful in the global scope of a web worker is significantly more narrow than we find out of the DOM. So we tend to author with While it isn't ideal, it saves us from the only other realistic option, splitting the code. If you have modular code, and pick off parts of a global scope and type them, and you are using modular code, you should be able to author isomorphic modules fairly easily. Here is an example of the most "bullet proof" way to get a reference to the global scope, which avoids any issues with CSP: const globalObject: any = (function (): any {
if (typeof global !== 'undefined') {
// global spec defines a reference to the global object called 'global'
// https://github.com/tc39/proposal-global
// `global` is also defined in NodeJS
return global;
}
else if (typeof window !== 'undefined') {
// window is defined in browsers
return window;
}
else if (typeof self !== 'undefined') {
// self is defined in WebWorkers
return self;
}
})(); |
@shamhub , no, you would use the global object instead of self
That being said, in your case, you don't need the global object. If you want to get around the typing errors, you can just use
|
@charlesbodman I have used second option but I get error |
@shamhub , it's because you're checking for worker support inside of the worker. No need. |
@charlesbodman Yes it works now. In JS, we have |
SharedWorker needs to have its own lib file. mind filing a new ticket to track creating that. |
logged #24323 to track adding |
@mhegazy @DanielRosenwasser we're also running into the incompatible I suppose the "right" approach would be for IDE support to better approximate compilation support by supporting multiple tsconfigs on the same folder that affect different combination of files. But that sounds hard and needs to be supported by the IDE proper as well. I'm not sure what the correct approach is right now. |
(Heads up, @mhegazy is no longer on the team. CCing @RyanCavanaugh) |
We should reorganize this a bunch
|
Any progress on this? I am having the same issue |
The worker self object is simply cast to any to make sure typescript does not complain. Actual typecheck may be restored once the following issue is fixed: microsoft/TypeScript#20595
There is a related problem that library developers (typings/ The only workaround I can see is to target "DOM" inside the webworker code (and declare all the webworker APIs that you need to use in order to make it compile) or to patch all the typings files and generate separate versions for use in webworkers, only. Although feasible, I don't like those workarounds. I would rather see the compiler be more lenient with respect to unused (with respect to the sources to are being compiled) declarations in a d.ts file. |
To add to my previous comment above: For libraries, there actually is a work around: It's also an all-or-nothing flag, so really having more control over this would be appreciated: Use the |
Though it is a little bit ugly, here is a method I've gotten to work:
This actually makes the intellisense work on the
If there's a cleaner syntax for this, I'd love a hint. :) |
@orta and I put our heads together on this to see if @RyanCavanaugh's proposed solution is workable. So far, we think Yes, with some caveats that we need to investigate. Here's are some notes; we'll work more on this soon.
|
Having just discussed this on Gitter, I realized that the general problem here isn't just about I actually have a similar problem to this today with miniSphere: the vast majority of a game will use the Sphere typings, but the build script-- So if there were a way to use separate typings per-file or even just per-directory, that would be an elegant solution to this problem, I think, and probably wouldn't even require modifying the |
In the meantime, the workaround I use is typing /* eslint-env worker */
const worker: Worker = self as any;
worker.addEventListener("message", (e) => {
worker.postMessage({hello: "world"});
}); You can even go further and type the messages: worker.ts /* eslint-env worker */
type TRequest = {
myrequest: number;
};
type TResponse = {
myresponse: number;
};
export interface IRequestWorker {
postMessage: (message: TRequest) => void;
onmessage: (message: MessageEvent<TResponse>) => void;
}
interface IResponseWorker {
postMessage: (message: TResponse) => void;
onmessage: (message: MessageEvent<TRequest>) => void;
}
const worker: IResponseWorker = self as any;
// Receive from the main thread
worker.onmessage = ({data: {myrequest}}) => {
console.log(myrequest);
// Send to the main thread
worker.postMessage({myresponse: 222});
}; main.ts /* eslint-env browser */
import type {IRequestWorker} from "./worker.ts";
const worker = new Worker(new URL("./worker.ts", import.meta.url)) as IRequestWorker;
// Receive from the worker
worker.onmessage = ({data: {myresponse}}) => {
console.log(myresponse);
};
// Send to the worker
worker.postMessage({myrequest: 111});
export {}; |
I got myself into a situation similar to #11093.
My project is designed to work either in the "main thread", with access to DOM, or as a WebWorker, where a different behavior kicks in. This was done for compatibility reasons and to have only one distributable js file and it's been working fine for the last two years.
In all this time I never specified the lib compiler option, only target ES5.
Today, as I'm experimenting some ES2015 stuff, I see that if I specify targets DOM,ES5,WebWorker,ES2015.Promise all hell breaks loose with errors. - Duplicate identifier, Subsequent variable declarations must have the same type.
Shouldn't this kind of mix be allowed in a project?
The text was updated successfully, but these errors were encountered: