Description
TypeScript Version: 3.5.0-dev.20190424
Search Terms:
generic type parameters broken, regression 3.4, type inference for mapped conditional types broken
Code
type UserArgs = {
select?: boolean
}
type Subset<T, U> = { [key in keyof T]: key extends keyof U ? T[key] : never }
function withBoundary<T extends UserArgs>(args?: Subset<T, UserArgs>): T {
return null as any
}
const boundaryResult = withBoundary({
select: true,
})
// In TypeScript@3.3:
/**
* typeof boundaryResult === {
* select: true
* }
*/
// In TypeScript@3.4 @ TypeScript@next:
/**
* typeof boundaryResult === UserArgs
*/
function withoutBoundary<T extends UserArgs>(args?: T): T {
return null as any
}
const withoutBoundaryResult = withoutBoundary({
select: true,
})
// In TypeScript@3.3:
/**
* typeof withoutBoundaryResult === {
* select: true
* }
*/
// In TypeScript@3.4 & TypeScript@next:
/**
* typeof withoutBoundaryResult === {
* select: true
* }
*/
Expected behavior:
I expect the return type of the withBoundary
function to actually include the fine-grain information of which concrete boolean value is provided for the select
property. It should have type {select: true}
.
Actual behavior:
Instead, it's typecasted to UserArgs
.
We need this behavior to work because we want to make sure that users of our library only pass in a "subset" and not a superset of the UserArgs
type into the withBoundary
function. As T extends UserArgs
is not sufficient to narrow that down, we use (args?: Subset<T, UserArgs>)
. This worked in 3.3 and is now broken in 3.4.
Related Issues: