You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I updated to 2.3.4 -> 2.4.0 and now I'm unable to do import * as lib from '@types/lib', as it throws an error: error TS6137: Cannot import type declaration files.
I thought that this was a great way to programatically include type definitions into a clearly defined namespace, which then gets scrubbed at compile time (as opposed to /// referencing them).
I can understand blocking the direct importing of def files in ambiguous contexts to help prevent runtime errors (i.e. if you import * as lib from 'lib', then you should expect it to only import a non-def file), but I feel that doing an import of something in the @types package namespace, or a file ending with .d.ts should be allowed, as it's explicitly importing typings.
It helps to work around things where you actually want types but don't use a library.
It's clear that you're not using an actual aws-lambda library, just the types.
It's also clear where the lambda namespace came from, so new developers to the code don't wonder where random namespaces might come from, which is what happens when you rely solely on the ambient type definition:
It helps to work around problems like defining types to library A which is designed to fit the same API as library B.
i.e. the mysql2 package is designed to fit mostly the same API as the mysql package, so you can cover the majority of usage by just defining this typescript def file:
you are importing the package. types are just illusion at design time. they do not exist at run time.
I know this, which is why I don't like the fact that it looks exactly like a normal import. It's code that isn't emitted, so shouldn't it be more recognisable as such?
use --types or "types" in your tsconfig.json to specify a list to types to import.
That's worse though as it means you then have seemingly undefined variables in your code. (see the AWS example in my first comment).
Both of these things make it easy to trip not only new developers up, but also trip yourself up.
I know this, which is why I don't like the fact that it looks exactly like a normal import. It's code that isn't emitted, so shouldn't it be more recognisable as such?
does it represent code that exists at runtime? if so, do not see the issue, if not, then why not model the run-time behavior more accurately.
Both of these things make it easy to trip not only new developers up, but also trip yourself up.
I am not sure i understand this. why would this be confusing? and why would @types be less confusing to a new developer?
@types is a pretty core concept in typescript, most tutorials introduce the namespace pretty early on, so all but the newest typescript devs would instantly recognise its meaning.
But relying on ambient defs means you can have a bunch of namespace that just exist in the code, with no clear way to discern what def they are from.
does it represent code that exists at runtime? if so, do not see the issue, if not, then why not model the run-time behavior more accurately.
It doesn't always represent code that exists at runtime, see the AWS example. The variables in the handler exist at runtime, but the types certainly do not.
The problem is that now there's no way to signify to a dev "hey these types exist solely for typings sake, there's no library involved, but here's where these namespace are coming from for future reference"
import lib from '@types/lib' will not be emitted, and can never be emitted - and in its definition of using @types, it is clear, and recognisable that this is how it will always be; just like Partial.
But import lib from 'lib' looks like it should be emitted, but if it's just being used for definitions it won't be emitted.
This is even more confusing in say the case of @types/aws-lambda. The aws-lambda npm package is a command line tool for deploying to lambda, but @types/aws-lambda is a set of typings specifically for the JS APIs provided by running code on lambda.
So if I do import * as lambda from "aws-lambda", what does that mean? it looks like i'm importing the aws-lambda cli package, or that I'm importing the APIs that lambda provides, when in actuality i'm only importing the typings for the aws lambda api.
Where as import * as lambda from "@types/aws-lambda" has exactly one meaning. I'm doing a design time import of typings for aws-lambda.
Both of the statements will not be emitted at compile time, but one is clear and predictable.
This may all seem like a problem solely for that typings package, but there would be other examples where you may solely want to import types, and want that to be clear.
Reacted by Thor Amorim, sdeprez, Joe Lapp, Parasrah, Elephant-Vessel, Felipe Aragão, Rob, Edu, Jerry Reptak, Shishir Anshuman and 3 more
Reacted by Hassan Khan, Edu, Tomáš Hübelbauer and John Dorlus
looks like you are looking for something like #2812. we have decided to no differentiate between imports in type and value space. and in 99% of the time the two are the same thing.
Where as import * as lambda from "@types/aws-lambda" has exactly one meaning. I'm doing a design time import of typings for aws-lambda.
or, you typed that thinking it gets you the actual import. as a matter of fact we allowed this in the past, then restricted it based on feedback.
Mohamed Hegazy (@mhegazy) What's the recommended path going forward then? Should we replace all imports to @types/aws-lambda with aws-lambda or is there a way to revert to older behaviour on TS2.4?
In the case of typings for aws-lambda, you can either do an import that looks like the real package, or you can rely on ambient typings (the ambient namespace is AWSLambda).
I didn't want to use the real fake import (partially above, partially because it goes against our lining standards), so I just went with using the ambient typing.
The linting standards flag importing of packages not listed as a dependency in package.json
Because we are using the package @types/aws-lambda, obviously an import of the package aws-lambda is flagged. Which in this case is exactly the thing you would want to flag.
Considering that the npm package aws-lambda (a cli tool for deploying lambda code) and @types/aws-lambda (typings for args that are provided when running on lambda) are pretty unrelated packages, I think the linting rule is doing its job perfectly.
As detailed in the thread above. If I could, I'd prefer to stick to importing the clearly defined @types/aws-lambda, but unfortunately it looks like support for that has been removed as of 2.4.
In the vast majority of cases, an import from a module specifier beginning with @types is a bug and will result in a runtime error. If you use a package management system that allows installing packages under aliases, you could work around the linter rule that way.
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.
Activity
mhegazy commentedon Jun 13, 2017
just import the package itself, and not the
@typesfile. i.e.import ... form "mysql"instead ofimport ... form "@types/mysql"bradzacher commentedon Jun 13, 2017
The problem I have with that is it looks like you're actually importing the package, when you're just using the typings.
I think there should be a way for you to show that you're explicitly importing typings, without forcing a dev to go look in the
package.jsonmhegazy commentedon Jun 13, 2017
you are importing the package. types are just illusion at design time. they do not exist at run time.
use
--typesor"types"in your tsconfig.json to specify a list to types to import.bradzacher commentedon Jun 13, 2017
I know this, which is why I don't like the fact that it looks exactly like a normal import. It's code that isn't emitted, so shouldn't it be more recognisable as such?
That's worse though as it means you then have seemingly undefined variables in your code. (see the AWS example in my first comment).
Both of these things make it easy to trip not only new developers up, but also trip yourself up.
mhegazy commentedon Jun 13, 2017
does it represent code that exists at runtime? if so, do not see the issue, if not, then why not model the run-time behavior more accurately.
I am not sure i understand this. why would this be confusing? and why would
@typesbe less confusing to a new developer?bradzacher commentedon Jun 13, 2017
@typesis a pretty core concept in typescript, most tutorials introduce the namespace pretty early on, so all but the newest typescript devs would instantly recognise its meaning.But relying on ambient defs means you can have a bunch of namespace that just exist in the code, with no clear way to discern what def they are from.
It doesn't always represent code that exists at runtime, see the AWS example. The variables in the handler exist at runtime, but the types certainly do not.
The problem is that now there's no way to signify to a dev "hey these types exist solely for typings sake, there's no library involved, but here's where these namespace are coming from for future reference"
mhegazy commentedon Jun 13, 2017
but is not that the case for all types.. why is
@types/sqldifferent from something likePartial? they all do not exist at runtime.bradzacher commentedon Jun 14, 2017
that's exactly my point.
import lib from '@types/lib'will not be emitted, and can never be emitted - and in its definition of using@types, it is clear, and recognisable that this is how it will always be; just likePartial.But
import lib from 'lib'looks like it should be emitted, but if it's just being used for definitions it won't be emitted.This is even more confusing in say the case of
@types/aws-lambda. Theaws-lambdanpm package is a command line tool for deploying to lambda, but@types/aws-lambdais a set of typings specifically for the JS APIs provided by running code on lambda.So if I do
import * as lambda from "aws-lambda", what does that mean? it looks like i'm importing theaws-lambdacli package, or that I'm importing the APIs that lambda provides, when in actuality i'm only importing the typings for the aws lambda api.Where as
import * as lambda from "@types/aws-lambda"has exactly one meaning. I'm doing a design time import of typings for aws-lambda.Both of the statements will not be emitted at compile time, but one is clear and predictable.
This may all seem like a problem solely for that typings package, but there would be other examples where you may solely want to import types, and want that to be clear.
mhegazy commentedon Jun 15, 2017
looks like you are looking for something like #2812. we have decided to no differentiate between imports in type and value space. and in 99% of the time the two are the same thing.
or, you typed that thinking it gets you the actual import. as a matter of fact we allowed this in the past, then restricted it based on feedback.
hassankhan commentedon Jun 27, 2017
Mohamed Hegazy (@mhegazy) What's the recommended path going forward then? Should we replace all imports to
@types/aws-lambdawithaws-lambdaor is there a way to revert to older behaviour on TS2.4?bradzacher commentedon Jun 27, 2017
In the case of typings for
aws-lambda, you can either do an import that looks like the real package, or you can rely on ambient typings (the ambient namespace isAWSLambda).I didn't want to use the real fake import (partially above, partially because it goes against our lining standards), so I just went with using the ambient typing.
hassankhan commentedon Jun 27, 2017
Thanks for the info Brad Zacher (@bradzacher)!! 👍
aluanhaddad commentedon Jun 27, 2017
It sounds like your linting standards need to be updated since they are encouraging you to use global variables.
bradzacher commentedon Jun 27, 2017
The linting standards flag importing of packages not listed as a dependency in
package.jsonBecause we are using the package
@types/aws-lambda, obviously an import of the packageaws-lambdais flagged. Which in this case is exactly the thing you would want to flag.Considering that the npm package
aws-lambda(a cli tool for deploying lambda code) and@types/aws-lambda(typings for args that are provided when running on lambda) are pretty unrelated packages, I think the linting rule is doing its job perfectly.As detailed in the thread above. If I could, I'd prefer to stick to importing the clearly defined
@types/aws-lambda, but unfortunately it looks like support for that has been removed as of 2.4.aluanhaddad commentedon Jun 28, 2017
In the vast majority of cases, an import from a module specifier beginning with
@typesis a bug and will result in a runtime error. If you use a package management system that allows installing packages under aliases, you could work around the linter rule that way.fix: error TS6137: Cannot import type declaration files. Consider imp…
mhegazy commentedon Aug 17, 2017
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.