Comments (23)
Correct 👍 But this isn't just in the namespace, process
is a variable that needs declaring at the top-level. There's a few fundamental limitations here. I'm not sure, but maybe we can propose a change in TypeScript to curb this because it definitely isn't the first time.
My initial thought is a TypeScript directive that'll ensure the file is always considered global or external. /cc @mhegazy @RyanCavanaugh How feasible would it be to allow import
at the top-level if there was something to declare this file as a global declaration?
from env-node.
Seems like a good change. I think both the read and write streams should just be updated to the tty
interfaces and not use streams directly.
from env-node.
They are totally different classes though. tty streams inherit from net.Socket
from env-node.
Ok, then what I should have said is to create new interfaces for this. I don't think you'd want a union here, TypeScript would still complain it doesn't exist until you do a type assertion then.
Edit: Sorry, you're right. Read the example wrong. You're definitely welcome to do a PR to quickly update as well 😄
from env-node.
Ok, so it turns out this is a real PITA to fix - any ideas? The issue is that the tty
, net
, stream
, etc. are all modules by process
it global. I wish there was a nice way in TypeScript to mix global with modules (like declare var process: Process from 'process'
or something).
from env-node.
@blakeembrey shouldn't this work?
import {Process} from 'process';
declare const process: Process;
Assuming Process
is an interface
from env-node.
No. You can't do that because the second you put import
at the top-level, it makes the definition an external module format and not global. That's sadly just the rules TypeScript uses.
from env-node.
And the other way around?
declare namespace NodeJS {
export interface Process {}
}
declare module 'process' {
type Process = NodeJS.Process;
export {Process};
}
from env-node.
Yes, that's possible - but it requires moving all of stream
, net
, tty
(just the pieces in use here) into the global NodeJS
scope. It's actually the trick that's currently in use today, I just didn't want to make that change right away because it is a huge change.
from env-node.
And you cannot use import
inside a namespace, right? I think that is the fundamental limitation here.
from env-node.
@blakeembrey It could be a new triple-slash directive.
Alternatively, it would also be enough if we could import
inside namespaces. Then we could declare the globals by referencing the type from the namespace.
declare const process: NodeJS.Process;
declare namespace NodeJS {
export {Process} from 'process';
}
from env-node.
I don't understand the question -- TypeScript always considers files as global or module depending on presence of top-level import
/ export
declarations. You can use declare global {
if you want something to go into the global scope from within a module file.
from env-node.
So we would change the whole declaration file to a module, but then put the majority of it inside declare global
. Interesting! Might make the whole code way more structured because we can put stream stuff inside the actual 'stream'
module, tty stuff inside 'tty'
, process inside 'process'
etc.
from env-node.
@blakeembrey Could we even make individual files for the core node modules that are purely external? And then have one index that imports everything and declares the globals?
from env-node.
@RyanCavanaugh And that's exactly our problem. We need to share an interface globally declare var process: Process
and within modules declare module "process"
. The pain here comes from the fact that some things have a very big module dependency chain to work (E.g. tty -> net -> stream
) which all have to be moved global just to make process
work. However, if we could import from a module into the global, this would be possible without polluting the global namespace with a ton of things that don't exist.
from env-node.
@felixfbecker Unfortunately that's not possible either, because we need to put declare module "stream"
so TypeScript can recognise them. So either way, all the files would need to be global.
Using declare global
may be possible with 2.0. Might be worth trying but I think the issue here is how TypeScript would treat this file. Since it's now external, I believe the global
declaration would only take effect after the externalised node.d.ts
module is imported. Is that correct @RyanCavanaugh?
from env-node.
@RyanCavanaugh I just tried out your suggestion, but it doesn't work:
declare module 'process' {
export interface Process {}
}
import {Process} from 'process';
declare global {
const process: Process; // Error: Module augmentation cannot introduce new names in the top level scope.
}
from env-node.
@felixfbecker I think the other issue with that is that import
at the top-level makes the file external, which results in declare module "process"
being an augmentation instead of a declaration of the original module. This, in turn, seems to result in errors with "process"
not being found to import from to start with. At least on the latest nightly (which 2.0 does fix the module augmentation error you see) occurs with test.d.ts(4,23): error TS2307: Cannot find module 'process'.
.
from env-node.
That error can be circumvented by doing:
process.d.ts
export interface Process {}
node.d.ts
import {Process} from './process';
declare global {
const process: Process; // Error: Module augmentation cannot introduce new names in the top level scope.
}
The error I mentioned remains though.
from env-node.
@felixfbecker Correct, but then there's no "process"
global module declared, only a ./process
external module. The error you mentioned is fixed in 2.0.
from env-node.
The only way around all this may be to combine module files, references and imports. E.g. Write declare "process" {}
in it's own file, use it as a reference, then import { Process } from 'process'
like your example above.
Edit: However, none of this fixes the concerns mentioned in #19 (comment) because having node.d.ts
as an external module probably won't be used how we want it to be.
from env-node.
@blakeembrey Besides the error that is fixed in TS2.0, I found a solution:
process.d.ts
declare module 'process' {
export interface Process {}
}
node.d.ts
/// <reference path="./process.d.ts" />
import {Process} from 'process';
declare global {
declare const process: Process;
}
from env-node.
Yes, that's the proposal I suggested above. But it does not fix the concern I expressed (also above).
from env-node.
Related Issues (20)
- Object.assign is missing in node 4/5/6 typings HOT 6
- Provide interface PipeOptions instead of { end?: boolean }
- (Re)export ReadWriteStream interface in 'stream' external module HOT 1
- Expose types from `ts-node`
- "connected" property missing from ChildProcess in Node 4.x and below HOT 1
- Error.stackTraceLimit is number in node6? HOT 1
- "exitCode" property missing on NodeJS.process
- Kill `http.ServerRequest` type
- extend type define of NodeJS.Process.env HOT 12
- util.inspect() does not accept {depth: null} with strictNullChecks
- declare `fs.Stats` as a class
- url.format() does not accept string
- What happened to TlsOptions? HOT 1
- readFileSync `options` can be null HOT 2
- Old definitions in registry HOT 2
- Broken with newest es6.lib.d.ts HOT 3
- Add secureOptions to https.createServer options
- 7.0.8 Breaks when used with @types/Core-js HOT 3
- Wrong vm.createContext signature HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from env-node.