microsoft / microsoft/TypeScript
Type guard cannot remove `undefined` from `Partial<T>[keyof T] | undefined`
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.4k
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 117
Description
Bug Report
When writing a function to merge object A with non-undefined values from object B into C where A is of type T and B is of type Partial<T>, I came across a situation where the type guard seems to be failing.
🔎 Search Terms
- type guard
- Partial
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about common-bugs-that-arent-bugs
⏯ Playground Link
Playground link with relevant code
💻 Code
function merge<T>(a: T, b: Partial<T>, keys: (keyof T)[]): T {
const v: T = { ...a };
for (const key of keys) {
const value = b[key];
if (value !== undefined) {
v[key] = value;
}
}
return v;
}
🙁 Actual behavior
There is an error at v[key] = value;:
Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'.
Type 'undefined' is not assignable to type 'T[keyof T]'.

Clearly value is NOT undefined, yet the compiler complains that it is.
🙂 Expected behavior
I would expect that the code compiled.
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 with the linked TypeScript Playground and reproduce the error in the generic merge function at v[key] = value after the value !== undefined guard. Trace the checker behavior for Partial[keyof T] and indexed assignment; done means the example compiles without weakening the intended type checking.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100