Description
π Search Terms
skipLibCheck, noImplicitAny clash, broken type, any, unknown
β Viability Checklist
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
β Suggestion
In case of an error (e.g. duplicated identifier) in declaration files, TypeScript treats types related to the error as any
. I suggest that TypeScript uses unknown
instead.
This could be implemented with a new strictness option.
π Motivating Example
Repro: https://github.com/frigus02/test-ts-skiplibcheck | on TS bug workbench
Setup:
-
2 different TypeScript libraries declare the same identifier with a different (incompatible) type, either using
declare global
ordeclare module
. Individually both libraries build and run correctly.E.g. libraries
a
andb
both declare a global identifierlib
.a
declares it as typestring
,b
as a namespace containing identifierbees
. -
One library somehow exposes a type inside of the duplicated identifier.
E.g. library
b
exports a function returningtypeof lib.bees
. -
A third library brings imports both
a
andb
.
Result:
-
Duplicated identifier
lib
is an error. The first seen declaration wins. Uses of the type as declared in the second declaration degenerate toany
. -
If
main
usesskipLibCheck: true
, this is only noticeable when you triggernoImplicitAny
, e.g. via a callback like.forEach(x =>
. This may be rare andany
can spread to other libraries. When an error does finally occur it can be really hard to track down where it's coming from.
π» Use Cases
-
What do you want to use this for?
Detect errors early. Prevent spread of
any
.Internally at Google we're still using https://github.com/angular/clutz for interop between TypeScript and Closure JavaScript. Clutz generates global namespaces. Every now and then 2 files generate the same identifier resulting in a clash as shown above.
Applications also sometimes end up with multiple versions of declaration files for the same third party library (brought in via different transitive dependencies), which can result in the same error. While that's a bug, a feature like this would help to avoid and debug these cases.
-
What shortcomings exist with current approaches?
skipLibCheck: false
is not feasible for us, because of longer compile time. -
What workarounds are you using in the meantime?
none