Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AllowJs - ts-check - Cannot find namespace #19547

Closed
jantimon opened this issue Oct 28, 2017 · 14 comments
Closed

AllowJs - ts-check - Cannot find namespace #19547

jantimon opened this issue Oct 28, 2017 · 14 comments
Labels
Duplicate An existing issue was already created

Comments

@jantimon
Copy link

jantimon commented Oct 28, 2017

Code

node_modules/@types/thirdParty/index.d.ts

export = demo;
declare namespace demo {
  foo: number;
}

main.js

// @ts-check
/// <reference types="thirdParty" />
const x: demo.foo;

Expected behavior:

I should be able to use the type foo of demo.
The example from above would work if but only if the thirdParty plugin also exports its namespace:

export as namespace demo;

I couldn't find any docs on what exactly export as namespace does.
Proably it would just add it to the global namespace which might not be the desired solution.

Actual behavior:

Without the exported namespace I receive error messages which are not helpful at all:

error TS2304: Cannot find name 'demo'
error TS2503: Cannot find namespace 'demo'

Suggestion:

Could we import everything which is exported from the index.d.ts file (like export = demo) to a name?
This would be useful for --allowJs checks where we can't import typings from another file.

// @ts-check
/// <reference types="thirdParty" name="thirdParty" />
@aluanhaddad
Copy link
Contributor

What is the shape of the actual package at runtime?

If demo is available as a global then the declaration needs to be updated to add the export as namespace demo clause as you described.

If it isn't available globally, then you won't be able to use it without importing its value in which case you will have access to the types.

@jantimon
Copy link
Author

In my hypothetical example demo won't be globally available.
How would it be possible to import types from that thirdParty plugin into a .js file which is using @ts-check?

@aluanhaddad
Copy link
Contributor

aluanhaddad commented Oct 28, 2017

If it's not available globally than using <reference types="..."/> is not correct.

How would it be possible to import types from that thirdParty plugin into a .js file which is using @ts-check ?

Different approaches are possible depending on how you load modules but let's say you're using CommonJS.

var demo = require('demo');

/**
  * @param x {demo.SomeType}
  */
function f(x) {}

It's worth mentioning that there is a syntax error in the declaration in the OP so it will not work as written.

@aluanhaddad
Copy link
Contributor

aluanhaddad commented Oct 28, 2017

Sorry, it appears that doesn't work. I thought it was supposed to work.

var demo = require('demo');

/**
  * @param {demo.SomeType} x // error: Cannot find namespace demo.
  */
function f(x) {}

But it works correctly when imported as the synthetic default using ESM syntax.

import demo from './demo';

/**
  * @param {demo.SomeType} x // OK
  */
function f(x) {x}

@jantimon
Copy link
Author

Unfortunate the oss ecosystem I am working on (webpack) still supports node 4 which is years away from ESM.. is there any other possible solution which doesn't require transpiling?

@aluanhaddad
Copy link
Contributor

aluanhaddad commented Oct 28, 2017

No, but since are already using Webpack, you can just use the synthetic default form. Recent versions of Webpack perform the hoisting.

I do think this is a bug however.

@jantimon
Copy link
Author

I am not using webpack but developing a webpack plugin

@aluanhaddad
Copy link
Contributor

You could always use tsc to transpile your JavaScript 😉 it will remove the import since it is only used in type position when it runs, but at that point you might as well just use TypeScript directly.

@jantimon
Copy link
Author

What might be a propper way to resolve this bug?
Is there anything I can do to fix it?

@aluanhaddad
Copy link
Contributor

aluanhaddad commented Oct 28, 2017

@DanielRosenwasser I'm just wondering if this is the intended behavior.

Perhaps it's a naive assumption but it seems like this scenario could be enabled and would be more natural for reusing existing declaration files.

I realize that import..require has special semantics but does it have to? Could var..require behave similarly in this context?

@DanielRosenwasser
Copy link
Member

I'm just wondering if this is the intended behavior.

No, I do think this should just work.

@jantimon
Copy link
Author

jantimon commented Oct 29, 2017

Thanks for all the additional information @DanielRosenwasser - #16489 and #18460 are almost duplicates for this topic and it seems the feature was added to the typescript 2.7 milestone by @mhegazy

@mhegazy mhegazy added the Duplicate An existing issue was already created label Oct 30, 2017
@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

5 participants