You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A conditional type should be narrowed when possible.
β When calling foo in the example below, types are as expected - We always require the x property to be defined in the object payload, and when we specify mode Y, we also require the y property to be defined
Within the foo function In the example below, the point type is completely useless
π΄ I expect the point type to be narrowed to Pick<TPoint, 'x' | 'y'> = { x: number; y: number } when we know that mode: 'Y', but I get a type error when I try to access any property of the object: Property 'y' does not exist on type 'Pick<TPoint, TMode extends "Y" ? "x" | "y" : "x">'.(2339)
π΄ I expect x to always be accessible from the point, but I get a type error when I try to access the property of the object: Property 'x' does not exist on type 'Pick<TPoint, TMode extends "Y" ? "x" | "y" : "x">'.(2339)
π Motivating Example
We would now be able to write functions where two or more parameters depend on each other:
typeTPoint={x: number; y: number; z: number};constfoo=<TModeextends'X'|'Y'>(mode: TMode,point: Pick<TPoint,TModeextends'Y' ? 'x'|'y' : 'x'>,)=>{if(mode==='Y'){returnpoint.x+point.y;}returnpoint.x;};foo('X',{x: 1});// @ts-expect-error: Object literal may only specify known properties, and 'y' does not exist in type 'Pick<TPoint, "x">'.(2353)foo('X',{x: 1,y: 2});// @ts-expect-error: Property 'y' is missing in type '{ x: number; }' but required in type 'Pick<TPoint, "x" | "y">'.(2345)foo('Y',{x: 1});foo('Y',{x: 1,y: 2});
π» Use Cases
What do you want to use this for?
When I have a function where the type of two parameters depend on each other.
What shortcomings exist with current approaches?
Using a combination of generics and conditional types, we are able to give the function a very nice type signature from the outside, but within the body of the function, the types are practically unusable.
What workarounds are you using in the meantime? // @ts-ignore everywhere
Alternatively wrap the parameters of the function in a single object payload
The text was updated successfully, but these errors were encountered:
π Search Terms
Conditional type inference narrow
β Viability Checklist
β Suggestion
A conditional type should be narrowed when possible.
β When calling
foo
in the example below, types are as expected - We always require thex
property to be defined in the object payload, and when we specify modeY
, we also require they
property to be definedWithin the
foo
function In the example below, thepoint
type is completely uselessπ΄ I expect the point type to be narrowed to
Pick<TPoint, 'x' | 'y'> = { x: number; y: number }
when we know thatmode: 'Y'
, but I get a type error when I try to access any property of the object:Property 'y' does not exist on type 'Pick<TPoint, TMode extends "Y" ? "x" | "y" : "x">'.(2339)
π΄ I expect
x
to always be accessible from the point, but I get a type error when I try to access the property of the object:Property 'x' does not exist on type 'Pick<TPoint, TMode extends "Y" ? "x" | "y" : "x">'.(2339)
π Motivating Example
We would now be able to write functions where two or more parameters depend on each other:
π» Use Cases
What do you want to use this for?
When I have a function where the type of two parameters depend on each other.
What shortcomings exist with current approaches?
Using a combination of generics and conditional types, we are able to give the function a very nice type signature from the outside, but within the body of the function, the types are practically unusable.
What workarounds are you using in the meantime?
// @ts-ignore
everywhereAlternatively wrap the parameters of the function in a single object payload
The text was updated successfully, but these errors were encountered: