Description
Linting Against Unused Locals and Variables
- We used
noUnusedLocals
/noUnusedParameters
. - Annoying when you comment code, try to run tests, but the build immediately fails.
- Very annoying.
- Often people delegate this to a linter, not TypeScript.
- Switching our codebase to use a linter would mean that linting fails after a test run.
- But currently we use our own compiler for this logic.
- In which we process JSDoc nodes for usages to determine if something is "unused".
- Trying to keep this logic is possible in eslint, but is very slow.
- Why do you even need to allow these?
- People using them in
@see
,@link
in TypeScript and relying on import elision. - Any other usage in
@type
in JavaScript files.
- People using them in
- Alternative: just slap some suppression comments, fix up some code to use
import(...)
types, call it a day.- Sure!
- But that means we're not dogfooding anymore.
- But arguably people should be using a linter.
- So don't have the feature at all?
- Not convinced there should be a black-or-white view of the world here. These options have value for people who don't want to add more tools.
- e.g. Other tools build better, but tsc has an emitter.
- We're okay with switching over.
5.4 Breaking Changes
Indexing with Intersections of String Literals and String Mapping Types Applied to Non-Generic Strings
-
Inconsistent intersections of string literal types and pattern string mapping types #57192
-
Breaks lead to finding that
"foo" & Lowercase<string>
is not recognized when indexing into{ "foo": SomeType }
- i.e.
{ "foo": SomeType }["foo" & Lowercase<string>]
- i.e.
-
We have a fix, we would like to try it out for 5.4 to reduce noise from breakage.
-
Need to make sure it doesn't break more!
Narrowing Conditional
-
T
has a constraint ofRecord<string, any>
, which any object type can be assigned to.- Recall: "any object" includes "any function"!
-
Previously,
DefaultValues
would fall into the true branch when trying to narrow against the constraint. -
Now, TypeScript acknowledges that
T
could possibly be either branch of the conditional type, and so narrowing doesn't
Intersection Reduction
-
Reduce intersections of constrained type variables and primitive types #56515
-
Move
Equals
constraint into an intersection type. reduxjs/react-redux#2123 -
Sent a PR upstream, fixed things.
-
Didn't work in one case, but seems like you can fix it by replacing an
any
with anunknown
. -
Aside, we feel weird about using these hacks to enforce that types are exact in parameters, rather than subtypes of each other.
- Why? You can now write
equals<T, U>(x: T & NoInfer<U>, y: U & NoInfer<T>)
and that works. - Feels less hacky than conditional types?
- Why? You can now write
Breaks on Vue
-
Resolution issue has been fixed.
-
The other break is annoying but sort of expected - the code either needs a type assertion or to be honest about the return type.
Implementing Functions that Return Conditional Types
- Have a PR that allows some return expressions to be assignable to a conditional type.
- The idea of the change: instead of seeing if the return expression is assignable, we look for if the tested type parameter is used uniquely by a parameter, and instantiate the return type with the narrowed type of the parameter.
- Most perf doesn't regress from this currently - because nobody is able to use this pattern.
- Constructed test file seems to do well where
- Want to get a sense of if we should continue with this concept.
- Really need to understand what the plan of implementation is. Like the idea at a high level.