Closed
Description
- Don't widen inferred return types when a contextual signature is available #40311 Don't widen inferred return types when a contextual signature is available
- Long-standing issue Don't widen return types of function expressions #241
- Problem today: When strictNullChecks is off, null and undefined are widened to any before generic inference occurs
- Example:
f<T>(a: () => T, b: () => T): T
underf(() => null, () => 1)
- Proposal: Widen them later
- Example:
- Problem today: Excess property checking doesn't occur on a return expression contextually typed by a concrete object type
- Examples: Countless
- By not widening, we retain freshness and can correctly detect excess properties
- Never widening is not the right solution
- You have to widen if you end up inferring a type for a binding, otherwise object literals stay "fresh" forever which is wrong outside of a transient context
- e.g.
const a = () => { x: 3, y: 4 }; const b: () => { x: number } = a
should be legal, but wouldn't be if we kept the freshness around
- e.g.
- Named function expressions can call themselves, which is problematic for functions with recursive returns
- You have to widen if you end up inferring a type for a binding, otherwise object literals stay "fresh" forever which is wrong outside of a transient context
- Solution: Only defer widening when a contextual signature type is present
- Found a bug in our own codebase
- Found real problems in DefinitelyTyped (either bad docs or copy/paste errors)
- Found things that appear to be bugs in RWC
- Limitations: Same problems when contextual types aren't present (e.g. overload positions)
- Investigate impact on binding patterns
const { x = () => true }/*: OptionalAnnotation */ = { x: () => false };
- What's going on in
wideningTuples2.ts
testcase?- Named function expressions observe their unwidened form when they reference themselves
- Options:
- Ignore
- Don't not widen named function expressions
- Rewire the lookup logic?
- Is this a blocker?
- What other manifestations of this might exist?
- Resolve offline
- Looks good to go for beta
- Please review!
- --noImplicitOverride #39669 pedantic override
override
without a flag to enforce it is mostly useless- But can't be on under
--strict
because no one has the ability to writeoverride
yet - Catch-22
- But can't be on under
- What is the ordering of keywords?
public abstract override foo()
public static override foo()
- pedantic index signatures
- PR is ready
- Remaining complaints are pre-known limitations
- Should investigate current perf penalty of narrowing on
x[i]
forconst i
- Last two attempts showed 5% perf hit
pedantic
thesaurus partypedantic
stringent
rigorous
(or if Ryan is listening,vigorous
🙃)conservative
- (no word at all)
indexedAccess
vsindexSignatures
- OT: we should have
--init-strict
or something - Wes brings up that we have
--noFoo
flags already that aren't part of--strict
--noUncheckedIndexedAccess
--noUncheckedIndexedAccesses
--noUncheckedIndexes
--noUncheckedIndices
--noUncheckedIndexing
--noImplicitBounds
--noImplicitAccess
--noImplicitIndexAccess
--noUncheckedLookup
--checkArrayBounds
--noImplicitIndexing
--undefinedIndexSignatures
--noBoundsAssumptions
--skepticalIndexAccesses
--🤨
--letsRunAPoll