microsoft / microsoft/TypeScript
Generic parameter type checking stops too early
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.4k
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 117
Description
🔎 Search Terms
generic, early, permature, defer
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
⏯ Playground Link
💻 Code
interface RefObject<T> {
current: T | null
}
declare function test(x: RefObject<number>): void;
declare function getRef(): RefObject<number | null>;
let v = getRef();
test(v);
🙁 Actual behavior
In the above code, RefObject is defined to always accept null in its current property. However, if one explicitly writes RefObject<number | null> and passes the result to a parameter accepting RefObject<number> TS reports a type error even though the types of the current property would have been the same. This happens with any type, not just null (e.g. if the definition of current was T | string.
🙂 Expected behavior
Since the current properties are equivalent after substituting the generic parameters, there should be no error. It seems like TS is stopping as soon as it sees RefObject<number | null> vs RefObject<number> even though substituting the generic parameter would result in the same type. This can be confirmed by creating a copy of the RefObject type like this:
interface RefObject<T> {
current: T | null
}
interface RefObject2<T> {
current: T | null
}
declare function test(x: RefObject<number>): void;
declare function getRef(): RefObject2<number | null>;
let v = getRef();
test(v);
Additional information about the issue
This affects the change in React's types between version 18 and 19, where the RefObject type changed current from T | null to only T. The uses of RefObject should add null instead, e.g. RefObject<HTMLDivElement | null>. Making libraries compatible with both the React 18 and React 19 types is difficult due to this TS issue. If a library updates its implementation to React 19, including RefObject<HTMLElement | null> in its definitions, consumers still using React 18 types will see TS errors.
cc. @eps1lon in case you know about this
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the linked TypeScript Playground reproductions and compare the RefObject and RefObject2 cases. Trace the type-checking path for generic instantiation and structural assignability; the issue names no repository files or tests. Done means the equivalent substituted property types are accepted without breaking existing generic checking behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100