mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 12:32:08 -06:00
Fixed an issue with destructured bindings from a generic union constraint not being narrowed correctly (#50221)
This commit is contained in:
parent
08af0b6bf0
commit
a8e13f7340
@ -25924,10 +25924,11 @@ namespace ts {
|
||||
if (!(links.flags & NodeCheckFlags.InCheckIdentifier)) {
|
||||
links.flags |= NodeCheckFlags.InCheckIdentifier;
|
||||
const parentType = getTypeForBindingElementParent(parent, CheckMode.Normal);
|
||||
const parentTypeConstraint = parentType && mapType(parentType, getBaseConstraintOrType);
|
||||
links.flags &= ~NodeCheckFlags.InCheckIdentifier;
|
||||
if (parentType && parentType.flags & TypeFlags.Union && !(parent.kind === SyntaxKind.Parameter && isSymbolAssigned(symbol))) {
|
||||
if (parentTypeConstraint && parentTypeConstraint.flags & TypeFlags.Union && !(parent.kind === SyntaxKind.Parameter && isSymbolAssigned(symbol))) {
|
||||
const pattern = declaration.parent;
|
||||
const narrowedType = getFlowTypeOfReference(pattern, parentType, parentType, /*flowContainer*/ undefined, location.flowNode);
|
||||
const narrowedType = getFlowTypeOfReference(pattern, parentTypeConstraint, parentTypeConstraint, /*flowContainer*/ undefined, location.flowNode);
|
||||
if (narrowedType.flags & TypeFlags.Never) {
|
||||
return neverType;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts(314,5): error TS7022: 'value1' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
|
||||
tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts(314,5): error TS7031: Binding element 'value1' implicitly has an 'any' type.
|
||||
tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts(334,5): error TS7022: 'value1' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
|
||||
tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts(334,5): error TS7031: Binding element 'value1' implicitly has an 'any' type.
|
||||
|
||||
|
||||
==== tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts (2 errors) ====
|
||||
@ -39,6 +39,26 @@ tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts(314,5): er
|
||||
}
|
||||
}
|
||||
|
||||
// repro #50206
|
||||
function f13<T extends Action>({ kind, payload }: T) {
|
||||
if (kind === 'A') {
|
||||
payload.toFixed();
|
||||
}
|
||||
if (kind === 'B') {
|
||||
payload.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
function f14<T extends Action>(t: T) {
|
||||
const { kind, payload } = t;
|
||||
if (kind === 'A') {
|
||||
payload.toFixed();
|
||||
}
|
||||
if (kind === 'B') {
|
||||
payload.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
type Action2 =
|
||||
| { kind: 'A', payload: number | undefined }
|
||||
| { kind: 'B', payload: string | undefined };
|
||||
|
||||
@ -35,6 +35,26 @@ function f12({ kind, payload }: Action) {
|
||||
}
|
||||
}
|
||||
|
||||
// repro #50206
|
||||
function f13<T extends Action>({ kind, payload }: T) {
|
||||
if (kind === 'A') {
|
||||
payload.toFixed();
|
||||
}
|
||||
if (kind === 'B') {
|
||||
payload.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
function f14<T extends Action>(t: T) {
|
||||
const { kind, payload } = t;
|
||||
if (kind === 'A') {
|
||||
payload.toFixed();
|
||||
}
|
||||
if (kind === 'B') {
|
||||
payload.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
type Action2 =
|
||||
| { kind: 'A', payload: number | undefined }
|
||||
| { kind: 'B', payload: string | undefined };
|
||||
@ -420,6 +440,24 @@ function f12({ kind, payload }) {
|
||||
payload; // never
|
||||
}
|
||||
}
|
||||
// repro #50206
|
||||
function f13({ kind, payload }) {
|
||||
if (kind === 'A') {
|
||||
payload.toFixed();
|
||||
}
|
||||
if (kind === 'B') {
|
||||
payload.toUpperCase();
|
||||
}
|
||||
}
|
||||
function f14(t) {
|
||||
const { kind, payload } = t;
|
||||
if (kind === 'A') {
|
||||
payload.toFixed();
|
||||
}
|
||||
if (kind === 'B') {
|
||||
payload.toUpperCase();
|
||||
}
|
||||
}
|
||||
function f20({ kind, payload }) {
|
||||
if (payload) {
|
||||
if (kind === 'A') {
|
||||
@ -662,6 +700,8 @@ type Action = {
|
||||
declare function f10({ kind, payload }: Action): void;
|
||||
declare function f11(action: Action): void;
|
||||
declare function f12({ kind, payload }: Action): void;
|
||||
declare function f13<T extends Action>({ kind, payload }: T): void;
|
||||
declare function f14<T extends Action>(t: T): void;
|
||||
type Action2 = {
|
||||
kind: 'A';
|
||||
payload: number | undefined;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -106,6 +106,69 @@ function f12({ kind, payload }: Action) {
|
||||
}
|
||||
}
|
||||
|
||||
// repro #50206
|
||||
function f13<T extends Action>({ kind, payload }: T) {
|
||||
>f13 : <T extends Action>({ kind, payload }: T) => void
|
||||
>kind : "A" | "B"
|
||||
>payload : string | number
|
||||
|
||||
if (kind === 'A') {
|
||||
>kind === 'A' : boolean
|
||||
>kind : "A" | "B"
|
||||
>'A' : "A"
|
||||
|
||||
payload.toFixed();
|
||||
>payload.toFixed() : string
|
||||
>payload.toFixed : (fractionDigits?: number | undefined) => string
|
||||
>payload : number
|
||||
>toFixed : (fractionDigits?: number | undefined) => string
|
||||
}
|
||||
if (kind === 'B') {
|
||||
>kind === 'B' : boolean
|
||||
>kind : "A" | "B"
|
||||
>'B' : "B"
|
||||
|
||||
payload.toUpperCase();
|
||||
>payload.toUpperCase() : string
|
||||
>payload.toUpperCase : () => string
|
||||
>payload : string
|
||||
>toUpperCase : () => string
|
||||
}
|
||||
}
|
||||
|
||||
function f14<T extends Action>(t: T) {
|
||||
>f14 : <T extends Action>(t: T) => void
|
||||
>t : T
|
||||
|
||||
const { kind, payload } = t;
|
||||
>kind : "A" | "B"
|
||||
>payload : string | number
|
||||
>t : Action
|
||||
|
||||
if (kind === 'A') {
|
||||
>kind === 'A' : boolean
|
||||
>kind : "A" | "B"
|
||||
>'A' : "A"
|
||||
|
||||
payload.toFixed();
|
||||
>payload.toFixed() : string
|
||||
>payload.toFixed : (fractionDigits?: number | undefined) => string
|
||||
>payload : number
|
||||
>toFixed : (fractionDigits?: number | undefined) => string
|
||||
}
|
||||
if (kind === 'B') {
|
||||
>kind === 'B' : boolean
|
||||
>kind : "A" | "B"
|
||||
>'B' : "B"
|
||||
|
||||
payload.toUpperCase();
|
||||
>payload.toUpperCase() : string
|
||||
>payload.toUpperCase : () => string
|
||||
>payload : string
|
||||
>toUpperCase : () => string
|
||||
}
|
||||
}
|
||||
|
||||
type Action2 =
|
||||
>Action2 : { kind: 'A'; payload: number | undefined; } | { kind: 'B'; payload: string | undefined; }
|
||||
|
||||
|
||||
@ -39,6 +39,26 @@ function f12({ kind, payload }: Action) {
|
||||
}
|
||||
}
|
||||
|
||||
// repro #50206
|
||||
function f13<T extends Action>({ kind, payload }: T) {
|
||||
if (kind === 'A') {
|
||||
payload.toFixed();
|
||||
}
|
||||
if (kind === 'B') {
|
||||
payload.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
function f14<T extends Action>(t: T) {
|
||||
const { kind, payload } = t;
|
||||
if (kind === 'A') {
|
||||
payload.toFixed();
|
||||
}
|
||||
if (kind === 'B') {
|
||||
payload.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
type Action2 =
|
||||
| { kind: 'A', payload: number | undefined }
|
||||
| { kind: 'B', payload: string | undefined };
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user