Skip to content

Commit

Permalink
Handle intersections in isGenericTypeWithoutNullableConstraint (#50497)
Browse files Browse the repository at this point in the history
* Handle intersections in isGenericTypeWithoutNullableConstraint

* Add regression test
  • Loading branch information
ahejlsberg committed Aug 29, 2022
1 parent ed6889c commit 6d170b4
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/compiler/checker.ts
Expand Up @@ -25789,8 +25789,10 @@ namespace ts {
!!(type.flags & TypeFlags.Instantiable && getBaseConstraintOrType(type).flags & (TypeFlags.Nullable | TypeFlags.Union));
}

function isGenericTypeWithoutNullableConstraint(type: Type) {
return !!(type.flags & TypeFlags.Instantiable && !maybeTypeOfKind(getBaseConstraintOrType(type), TypeFlags.Nullable));
function isGenericTypeWithoutNullableConstraint(type: Type): boolean {
return type.flags & TypeFlags.Intersection ?
some((type as IntersectionType).types, isGenericTypeWithoutNullableConstraint) :
!!(type.flags & TypeFlags.Instantiable && !maybeTypeOfKind(getBaseConstraintOrType(type), TypeFlags.Nullable));
}

function hasContextualTypeWithNoGenericTypes(node: Node, checkMode: CheckMode | undefined) {
Expand Down
8 changes: 8 additions & 0 deletions tests/baselines/reference/controlFlowGenericTypes.errors.txt
Expand Up @@ -240,4 +240,12 @@ tests/cases/conformance/controlFlow/controlFlowGenericTypes.ts(168,9): error TS2
control[key] = value;
}
}

// Repro from #50465

type Column<T> = (keyof T extends never ? { id?: number | string } : { id: T }) & { title?: string; }

function getColumnProperty<T>(column: Column<T>, key: keyof Column<T>) {
return column[key];
}

11 changes: 11 additions & 0 deletions tests/baselines/reference/controlFlowGenericTypes.js
Expand Up @@ -210,6 +210,14 @@ function update<T extends Control, K extends keyof T>(control : T | undefined, k
control[key] = value;
}
}

// Repro from #50465

type Column<T> = (keyof T extends never ? { id?: number | string } : { id: T }) & { title?: string; }

function getColumnProperty<T>(column: Column<T>, key: keyof Column<T>) {
return column[key];
}


//// [controlFlowGenericTypes.js]
Expand Down Expand Up @@ -368,3 +376,6 @@ function update(control, key, value) {
control[key] = value;
}
}
function getColumnProperty(column, key) {
return column[key];
}
26 changes: 26 additions & 0 deletions tests/baselines/reference/controlFlowGenericTypes.symbols
Expand Up @@ -626,3 +626,29 @@ function update<T extends Control, K extends keyof T>(control : T | undefined, k
}
}

// Repro from #50465

type Column<T> = (keyof T extends never ? { id?: number | string } : { id: T }) & { title?: string; }
>Column : Symbol(Column, Decl(controlFlowGenericTypes.ts, 210, 1))
>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 214, 12))
>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 214, 12))
>id : Symbol(id, Decl(controlFlowGenericTypes.ts, 214, 43))
>id : Symbol(id, Decl(controlFlowGenericTypes.ts, 214, 70))
>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 214, 12))
>title : Symbol(title, Decl(controlFlowGenericTypes.ts, 214, 83))

function getColumnProperty<T>(column: Column<T>, key: keyof Column<T>) {
>getColumnProperty : Symbol(getColumnProperty, Decl(controlFlowGenericTypes.ts, 214, 101))
>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 216, 27))
>column : Symbol(column, Decl(controlFlowGenericTypes.ts, 216, 30))
>Column : Symbol(Column, Decl(controlFlowGenericTypes.ts, 210, 1))
>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 216, 27))
>key : Symbol(key, Decl(controlFlowGenericTypes.ts, 216, 48))
>Column : Symbol(Column, Decl(controlFlowGenericTypes.ts, 210, 1))
>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 216, 27))

return column[key];
>column : Symbol(column, Decl(controlFlowGenericTypes.ts, 216, 30))
>key : Symbol(key, Decl(controlFlowGenericTypes.ts, 216, 48))
}

19 changes: 19 additions & 0 deletions tests/baselines/reference/controlFlowGenericTypes.types
Expand Up @@ -583,3 +583,22 @@ function update<T extends Control, K extends keyof T>(control : T | undefined, k
}
}

// Repro from #50465

type Column<T> = (keyof T extends never ? { id?: number | string } : { id: T }) & { title?: string; }
>Column : Column<T>
>id : string | number | undefined
>id : T
>title : string | undefined

function getColumnProperty<T>(column: Column<T>, key: keyof Column<T>) {
>getColumnProperty : <T>(column: Column<T>, key: keyof Column<T>) => Column<T>["title" | keyof (keyof T extends never ? { id?: string | number | undefined; } : { id: T; })]
>column : Column<T>
>key : "title" | keyof (keyof T extends never ? { id?: string | number | undefined; } : { id: T; })

return column[key];
>column[key] : Column<T>["title" | keyof (keyof T extends never ? { id?: string | number | undefined; } : { id: T; })]
>column : Column<T>
>key : "title" | keyof (keyof T extends never ? { id?: string | number | undefined; } : { id: T; })
}

Expand Up @@ -211,3 +211,11 @@ function update<T extends Control, K extends keyof T>(control : T | undefined, k
control[key] = value;
}
}

// Repro from #50465

type Column<T> = (keyof T extends never ? { id?: number | string } : { id: T }) & { title?: string; }

function getColumnProperty<T>(column: Column<T>, key: keyof Column<T>) {
return column[key];
}

0 comments on commit 6d170b4

Please sign in to comment.