Short answer
Read the two types in the message. If the argument includes undefined or null, check for it before the call or give a default. If it is string where a set of literal strings is expected, keep the literal type with as const or a type annotation. If it is an object, the indented lines under the error name the property that is missing or has the wrong type. Avoid as casts that only silence the error: they move the crash to runtime.
Why the types do not match, and the fix
01
undefined or null in the argument
Optional props, find(), environment variables and form values can all be undefined. Handle that case before the call, so the type inside the if is the plain type.
const apiUrl = process.env.API_URL; if (!apiUrl) throw new Error('API_URL is not set'); connect(apiUrl); // string, not string | undefined02
A string where specific strings are expected
let method = 'GET' widens to string, which a parameter typed 'GET' | 'POST' rejects. Use const, as const, or annotate the variable with the union.
type Method = 'GET' | 'POST'; const method: Method = 'GET'; const options = { method: 'GET' } as const;03
An object that is missing a property or has the wrong shape
“The basic rule for TypeScript’s structural type system is that x is compatible with y if y has at least the same members as x.” TypeScript, Type compatibility
TypeScript compares objects by their members. The lines under the error show the first property that does not fit. Add it, fix its type, or change the parameter type if the function really accepts less.
04
React event and ref types
Passing a handler typed for one element to another (ChangeEvent<HTMLInputElement> on a select) or a ref of the wrong element type gives the same kind of mismatch. In JSX it is reported as TS2322 on the prop; TS2345 appears when you call the handler yourself. Type the handler for the element it is attached to.
const onChange = (e: React.ChangeEvent<HTMLSelectElement>) => setPlan(e.target.value);
Checked against the vendor’s docs on : TypeScript Handbook: Type compatibility; TypeScript Handbook: Narrowing.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
Related: TypeScript “Type is not assignable to type” · TypeScript “Object is possibly null” · TypeScript “Property does not exist on type”