diff --git a/tsc/internal/checker/checker.go b/tsc/internal/checker/checker.go index 10ddb3c0c88b4..8a13ae594a8a1 100644 --- a/tsc/internal/checker/checker.go +++ b/tsc/internal/checker/checker.go @@ -31371,7 +31371,7 @@ func (d *ObjectLiteralDiscriminator) name(index int) string { return d.members[index-len(d.props)].Name() } -func (d *ObjectLiteralDiscriminator) matches(index int, t *Type) bool { +func (d *ObjectLiteralDiscriminator) matches(index int, t *Type, _ bool) bool { var propType *Type if index < len(d.props) { prop := d.props[index] diff --git a/tsc/internal/checker/inference.go b/tsc/internal/checker/inference.go index 02c7d009b9ec5..b6fc9ecea58f1 100644 --- a/tsc/internal/checker/inference.go +++ b/tsc/internal/checker/inference.go @@ -247,10 +247,16 @@ func (c *Checker) inferFromTypes(n *InferenceState, source *Type, target *Type) case target.flags&TypeFlagsConditional != 0: c.invokeOnce(n, source, target, (*Checker).inferToConditionalType) case target.flags&TypeFlagsUnionOrIntersection != 0: - c.inferToMultipleTypes(n, source, target.Types(), target.flags) + c.inferToUnionOrIntersectionType(n, source, target) case source.flags&TypeFlagsUnion != 0: - // Source is a union or intersection type, infer from each constituent type - for _, sourceType := range source.Types() { + sources := source.Types() + if discriminants := c.getInferenceDiscriminants(source, target); len(discriminants) != 0 { + discriminator := &TypeDiscriminator{c: c, props: discriminants, reverse: true, isRelatedTo: c.compareTypesComparableSimple} + if filtered := c.discriminateTypesByDiscriminableItems(source, discriminator); filtered != nil { + sources = filtered + } + } + for _, sourceType := range sources { c.inferFromTypes(n, sourceType, target) } case target.flags&TypeFlagsTemplateLiteral != 0: @@ -456,7 +462,26 @@ func getTypeListDepth(types []*Type, maxDepth int) int { return depth } -func (c *Checker) inferToMultipleTypes(n *InferenceState, source *Type, targets []*Type, targetFlags TypeFlags) { +func (c *Checker) inferToUnionOrIntersectionType(n *InferenceState, source *Type, target *Type) { + // Each entry contains the remaining allowed targets for the corresponding source constituent. + // A nil entry means unrestricted. + var filteredTargetsBySource [][]*Type + if target.flags&TypeFlagsUnion != 0 { + sources := source.Distributed() + filteredTargetsBySource = make([][]*Type, len(sources)) + for i, s := range sources { + if discriminants := c.getInferenceDiscriminants(target, s); len(discriminants) != 0 { + discriminator := &TypeDiscriminator{c: c, props: discriminants, isRelatedTo: c.compareTypesComparableSimple} + if filtered := c.discriminateTypesByDiscriminableItems(target, discriminator); filtered != nil { + filteredTargetsBySource[i] = filtered + } + } + } + } + c.inferToMultipleTypes(n, source, target.Types(), target.flags, filteredTargetsBySource) +} + +func (c *Checker) inferToMultipleTypes(n *InferenceState, source *Type, targets []*Type, targetFlags TypeFlags, filteredTargetsBySource [][]*Type) { typeVariableCount := 0 if targetFlags&TypeFlagsUnion != 0 { var nakedTypeVariable *Type @@ -476,8 +501,22 @@ func (c *Checker) inferToMultipleTypes(n *InferenceState, source *Type, targets if getInferenceInfoForType(n, t) != nil { nakedTypeVariable = t typeVariableCount++ + // Naked type parameters still consume their entries in the filtered target lists. + for i, remaining := range filteredTargetsBySource { + if len(remaining) != 0 && remaining[0] == t { + filteredTargetsBySource[i] = remaining[1:] + } + } } else { for i := range sources { + if len(filteredTargetsBySource) != 0 && filteredTargetsBySource[i] != nil { + // Filtering preserves union order, so the next allowed target must be first. + remaining := filteredTargetsBySource[i] + if len(remaining) == 0 || remaining[0] != t { + continue + } + filteredTargetsBySource[i] = remaining[1:] + } saveInferencePriority := n.inferencePriority n.inferencePriority = InferencePriorityMaxValue c.inferFromTypes(n, sources[i], t) @@ -558,7 +597,7 @@ func getSingleTypeVariableFromIntersectionTypes(n *InferenceState, types []*Type func (c *Checker) inferToMultipleTypesWithPriority(n *InferenceState, source *Type, targets []*Type, targetFlags TypeFlags, newPriority InferencePriority) { savePriority := n.priority n.priority |= newPriority - c.inferToMultipleTypes(n, source, targets, targetFlags) + c.inferToMultipleTypes(n, source, targets, targetFlags, nil) n.priority = savePriority } @@ -1193,6 +1232,16 @@ func (c *Checker) replaceIndexedAccess(instantiable *Type, t *Type, replacement return c.instantiateType(instantiable, newTypeMapper([]*Type{t.AsIndexedAccessType().indexType, t.AsIndexedAccessType().objectType}, []*Type{c.getNumberLiteralType(0), c.createTupleType([]*Type{replacement})})) } +func (c *Checker) getInferenceDiscriminants(source *Type, target *Type) []*ast.Symbol { + if target.flags&TypeFlagsObject == 0 { + return nil + } + literalProps := core.Filter(c.getPropertiesOfType(target), func(prop *ast.Symbol) bool { + return isLiteralType(c.getNonMissingTypeOfSymbol(prop)) + }) + return c.findDiscriminantProperties(literalProps, source) +} + func (c *Checker) typesDefinitelyUnrelated(source *Type, target *Type) bool { // Two tuple types with incompatible arities are definitely unrelated. // Two object types that each have a property that is unmatched in the other are definitely unrelated. diff --git a/tsc/internal/checker/relater.go b/tsc/internal/checker/relater.go index d3b6c86014498..88ac801cc6e73 100644 --- a/tsc/internal/checker/relater.go +++ b/tsc/internal/checker/relater.go @@ -132,6 +132,13 @@ func (c *Checker) compareTypesAssignableSimple(source *Type, target *Type) Terna return TernaryFalse } +func (c *Checker) compareTypesComparableSimple(source *Type, target *Type) Ternary { + if c.isTypeRelatedTo(source, target, c.comparableRelation) { + return TernaryTrue + } + return TernaryFalse +} + func (c *Checker) compareTypesAssignableWorker(source *Type, target *Type, reportErrors bool) Ternary { if c.isTypeRelatedTo(source, target, c.assignableRelation) { return TernaryTrue @@ -1031,6 +1038,7 @@ type TypeDiscriminator struct { c *Checker props []*ast.Symbol isRelatedTo func(*Type, *Type) Ternary + reverse bool } func (d *TypeDiscriminator) len() int { @@ -1041,10 +1049,18 @@ func (d *TypeDiscriminator) name(index int) string { return d.props[index].Name() } -func (d *TypeDiscriminator) matches(index int, t *Type) bool { - propType := d.c.getTypeOfSymbol(d.props[index]) - for _, s := range propType.Distributed() { - if d.isRelatedTo(s, t) != TernaryFalse { +func (d *TypeDiscriminator) matches(index int, t *Type, isOptional bool) bool { + // Two optional discriminants always overlap through absence. Under strictNullChecks this is what the + // relation below would conclude anyway, so skip the property type resolution and the comparisons. + if isOptional && d.c.strictNullChecks && d.props[index].Flags()&ast.SymbolFlagsOptional != 0 { + return true + } + sourceType, targetType := d.c.getTypeOfSymbol(d.props[index]), t + if d.reverse { + sourceType, targetType = targetType, sourceType + } + for _, sourceType := range sourceType.Distributed() { + if d.isRelatedTo(sourceType, targetType) != TernaryFalse { return true } } @@ -1197,12 +1213,21 @@ func (c *Checker) mapTypesByKeyProperty(types []*Type, keyPropertyName string) m } type Discriminator interface { - len() int // Number of discriminant properties - name(index int) string // Property name of index-th discriminator - matches(index int, t *Type) bool // True if index-th discriminator matches the given type + len() int // Number of discriminant properties + name(index int) string // Property name of index-th discriminator + matches(index int, t *Type, isOptional bool) bool // True if index-th discriminator matches the given type, which is optional if isOptional is set } func (c *Checker) discriminateTypeByDiscriminableItems(target *Type, discriminator Discriminator) *Type { + if filtered := c.discriminateTypesByDiscriminableItems(target, discriminator); filtered != nil { + return c.getUnionTypeEx(filtered, UnionReductionNone, nil, nil) + } + return target +} + +// Returns the constituents of the union target that are not ruled out by the discriminator, in union order, +// or nil when the discriminator rules out nothing (or everything, which is treated the same way). +func (c *Checker) discriminateTypesByDiscriminableItems(target *Type, discriminator Discriminator) []*Type { types := target.Types() include := make([]Ternary, len(types)) for i, t := range types { @@ -1217,9 +1242,17 @@ func (c *Checker) discriminateTypeByDiscriminableItems(target *Type, discriminat matched := false for i := range types { if include[i] != TernaryFalse { - targetType := c.getTypeOfPropertyOrIndexSignatureOfType(types[i], discriminator.name(n)) + name := discriminator.name(n) + var targetType *Type + isOptional := false + if prop := c.getPropertyOfType(types[i], name); prop != nil { + targetType = c.getTypeOfSymbol(prop) + isOptional = prop.Flags()&ast.SymbolFlagsOptional != 0 + } else if indexInfo := c.getApplicableIndexInfoForName(types[i], name); indexInfo != nil { + targetType = c.addOptionalityEx(indexInfo.valueType, true /*isProperty*/, true /*isOptional*/) + } if targetType != nil { - if discriminator.matches(n, targetType) { + if discriminator.matches(n, targetType, isOptional) { matched = true } else { include[i] = TernaryMaybe @@ -1245,12 +1278,11 @@ func (c *Checker) discriminateTypeByDiscriminableItems(target *Type, discriminat filteredTypes = append(filteredTypes, t) } } - filtered := c.getUnionTypeEx(filteredTypes, UnionReductionNone, nil, nil) - if filtered.flags&TypeFlagsNever == 0 { - return filtered + if len(filteredTypes) != 0 { + return filteredTypes } } - return target + return nil } func (c *Checker) filterPrimitivesIfContainsNonPrimitive(unionType *Type) *Type { diff --git a/tsc/testdata/baselines/reference/compiler/classExtendedDiscriminatedUnionInference.js b/tsc/testdata/baselines/reference/compiler/classExtendedDiscriminatedUnionInference.js new file mode 100644 index 0000000000000..5362928da789c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/classExtendedDiscriminatedUnionInference.js @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/classExtendedDiscriminatedUnionInference.ts] //// + +//// [classExtendedDiscriminatedUnionInference.ts] +declare class LocalController { + isLocal: true; + getProps(a: T, b: U): void; +} +declare class GlobalController { + isLocal: false; + // N.B.: Parameter type order is reversed + getProps(a: U, b: T): void; +} + +class FailWithTS42 extends LocalController<{ foo: any }, { bar: any }> { } +const p = new FailWithTS42(); + +declare function createEnhancer1(Wrapper: GlobalController | LocalController): [T, U]; +const q1 = createEnhancer1(p); +const q2 = createEnhancer1(p as LocalController<{ foo: any }, { bar: any }>); // structurally identical type to the above + + +//// [classExtendedDiscriminatedUnionInference.js] +"use strict"; +class FailWithTS42 extends LocalController { +} +const p = new FailWithTS42(); +const q1 = createEnhancer1(p); +const q2 = createEnhancer1(p); // structurally identical type to the above diff --git a/tsc/testdata/baselines/reference/compiler/classExtendedDiscriminatedUnionInference.symbols b/tsc/testdata/baselines/reference/compiler/classExtendedDiscriminatedUnionInference.symbols new file mode 100644 index 0000000000000..e1ca3059fc7d0 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/classExtendedDiscriminatedUnionInference.symbols @@ -0,0 +1,72 @@ +//// [tests/cases/compiler/classExtendedDiscriminatedUnionInference.ts] //// + +=== classExtendedDiscriminatedUnionInference.ts === +declare class LocalController { +>LocalController : Symbol(LocalController, Decl(classExtendedDiscriminatedUnionInference.ts, 0, 0)) +>T : Symbol(T, Decl(classExtendedDiscriminatedUnionInference.ts, 0, 30)) +>U : Symbol(U, Decl(classExtendedDiscriminatedUnionInference.ts, 0, 32)) + + isLocal: true; +>isLocal : Symbol(LocalController.isLocal, Decl(classExtendedDiscriminatedUnionInference.ts, 0, 37)) + + getProps(a: T, b: U): void; +>getProps : Symbol(LocalController.getProps, Decl(classExtendedDiscriminatedUnionInference.ts, 1, 18)) +>a : Symbol(a, Decl(classExtendedDiscriminatedUnionInference.ts, 2, 13)) +>T : Symbol(T, Decl(classExtendedDiscriminatedUnionInference.ts, 0, 30)) +>b : Symbol(b, Decl(classExtendedDiscriminatedUnionInference.ts, 2, 18)) +>U : Symbol(U, Decl(classExtendedDiscriminatedUnionInference.ts, 0, 32)) +} +declare class GlobalController { +>GlobalController : Symbol(GlobalController, Decl(classExtendedDiscriminatedUnionInference.ts, 3, 1)) +>T : Symbol(T, Decl(classExtendedDiscriminatedUnionInference.ts, 4, 31)) +>U : Symbol(U, Decl(classExtendedDiscriminatedUnionInference.ts, 4, 33)) + + isLocal: false; +>isLocal : Symbol(GlobalController.isLocal, Decl(classExtendedDiscriminatedUnionInference.ts, 4, 38)) + + // N.B.: Parameter type order is reversed + getProps(a: U, b: T): void; +>getProps : Symbol(GlobalController.getProps, Decl(classExtendedDiscriminatedUnionInference.ts, 5, 19)) +>a : Symbol(a, Decl(classExtendedDiscriminatedUnionInference.ts, 7, 13)) +>U : Symbol(U, Decl(classExtendedDiscriminatedUnionInference.ts, 4, 33)) +>b : Symbol(b, Decl(classExtendedDiscriminatedUnionInference.ts, 7, 18)) +>T : Symbol(T, Decl(classExtendedDiscriminatedUnionInference.ts, 4, 31)) +} + +class FailWithTS42 extends LocalController<{ foo: any }, { bar: any }> { } +>FailWithTS42 : Symbol(FailWithTS42, Decl(classExtendedDiscriminatedUnionInference.ts, 8, 1)) +>LocalController : Symbol(LocalController, Decl(classExtendedDiscriminatedUnionInference.ts, 0, 0)) +>foo : Symbol(foo, Decl(classExtendedDiscriminatedUnionInference.ts, 10, 44)) +>bar : Symbol(bar, Decl(classExtendedDiscriminatedUnionInference.ts, 10, 58)) + +const p = new FailWithTS42(); +>p : Symbol(p, Decl(classExtendedDiscriminatedUnionInference.ts, 11, 5)) +>FailWithTS42 : Symbol(FailWithTS42, Decl(classExtendedDiscriminatedUnionInference.ts, 8, 1)) + +declare function createEnhancer1(Wrapper: GlobalController | LocalController): [T, U]; +>createEnhancer1 : Symbol(createEnhancer1, Decl(classExtendedDiscriminatedUnionInference.ts, 11, 29)) +>T : Symbol(T, Decl(classExtendedDiscriminatedUnionInference.ts, 13, 33)) +>U : Symbol(U, Decl(classExtendedDiscriminatedUnionInference.ts, 13, 35)) +>Wrapper : Symbol(Wrapper, Decl(classExtendedDiscriminatedUnionInference.ts, 13, 39)) +>GlobalController : Symbol(GlobalController, Decl(classExtendedDiscriminatedUnionInference.ts, 3, 1)) +>T : Symbol(T, Decl(classExtendedDiscriminatedUnionInference.ts, 13, 33)) +>U : Symbol(U, Decl(classExtendedDiscriminatedUnionInference.ts, 13, 35)) +>LocalController : Symbol(LocalController, Decl(classExtendedDiscriminatedUnionInference.ts, 0, 0)) +>T : Symbol(T, Decl(classExtendedDiscriminatedUnionInference.ts, 13, 33)) +>U : Symbol(U, Decl(classExtendedDiscriminatedUnionInference.ts, 13, 35)) +>T : Symbol(T, Decl(classExtendedDiscriminatedUnionInference.ts, 13, 33)) +>U : Symbol(U, Decl(classExtendedDiscriminatedUnionInference.ts, 13, 35)) + +const q1 = createEnhancer1(p); +>q1 : Symbol(q1, Decl(classExtendedDiscriminatedUnionInference.ts, 14, 5)) +>createEnhancer1 : Symbol(createEnhancer1, Decl(classExtendedDiscriminatedUnionInference.ts, 11, 29)) +>p : Symbol(p, Decl(classExtendedDiscriminatedUnionInference.ts, 11, 5)) + +const q2 = createEnhancer1(p as LocalController<{ foo: any }, { bar: any }>); // structurally identical type to the above +>q2 : Symbol(q2, Decl(classExtendedDiscriminatedUnionInference.ts, 15, 5)) +>createEnhancer1 : Symbol(createEnhancer1, Decl(classExtendedDiscriminatedUnionInference.ts, 11, 29)) +>p : Symbol(p, Decl(classExtendedDiscriminatedUnionInference.ts, 11, 5)) +>LocalController : Symbol(LocalController, Decl(classExtendedDiscriminatedUnionInference.ts, 0, 0)) +>foo : Symbol(foo, Decl(classExtendedDiscriminatedUnionInference.ts, 15, 49)) +>bar : Symbol(bar, Decl(classExtendedDiscriminatedUnionInference.ts, 15, 63)) + diff --git a/tsc/testdata/baselines/reference/compiler/classExtendedDiscriminatedUnionInference.types b/tsc/testdata/baselines/reference/compiler/classExtendedDiscriminatedUnionInference.types new file mode 100644 index 0000000000000..d0ccdcdf48322 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/classExtendedDiscriminatedUnionInference.types @@ -0,0 +1,59 @@ +//// [tests/cases/compiler/classExtendedDiscriminatedUnionInference.ts] //// + +=== classExtendedDiscriminatedUnionInference.ts === +declare class LocalController { +>LocalController : LocalController + + isLocal: true; +>isLocal : true +>true : true + + getProps(a: T, b: U): void; +>getProps : (a: T, b: U) => void +>a : T +>b : U +} +declare class GlobalController { +>GlobalController : GlobalController + + isLocal: false; +>isLocal : false +>false : false + + // N.B.: Parameter type order is reversed + getProps(a: U, b: T): void; +>getProps : (a: U, b: T) => void +>a : U +>b : T +} + +class FailWithTS42 extends LocalController<{ foo: any }, { bar: any }> { } +>FailWithTS42 : FailWithTS42 +>LocalController : LocalController<{ foo: any; }, { bar: any; }> +>foo : any +>bar : any + +const p = new FailWithTS42(); +>p : FailWithTS42 +>new FailWithTS42() : FailWithTS42 +>FailWithTS42 : typeof FailWithTS42 + +declare function createEnhancer1(Wrapper: GlobalController | LocalController): [T, U]; +>createEnhancer1 : (Wrapper: GlobalController | LocalController) => [T, U] +>Wrapper : GlobalController | LocalController + +const q1 = createEnhancer1(p); +>q1 : [{ foo: any; }, { bar: any; }] +>createEnhancer1(p) : [{ foo: any; }, { bar: any; }] +>createEnhancer1 : (Wrapper: GlobalController | LocalController) => [T, U] +>p : FailWithTS42 + +const q2 = createEnhancer1(p as LocalController<{ foo: any }, { bar: any }>); // structurally identical type to the above +>q2 : [{ foo: any; }, { bar: any; }] +>createEnhancer1(p as LocalController<{ foo: any }, { bar: any }>) : [{ foo: any; }, { bar: any; }] +>createEnhancer1 : (Wrapper: GlobalController | LocalController) => [T, U] +>p as LocalController<{ foo: any }, { bar: any }> : LocalController<{ foo: any; }, { bar: any; }> +>p : FailWithTS42 +>foo : any +>bar : any + diff --git a/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=false).errors.txt b/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=false).errors.txt new file mode 100644 index 0000000000000..54dea5cbc919e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=false).errors.txt @@ -0,0 +1,51 @@ +contextualTypingDiscriminantOverlap.ts(21,16): error TS7006: Parameter 'value' implicitly has an 'any' type. +contextualTypingDiscriminantOverlap.ts(40,16): error TS7006: Parameter 'value' implicitly has an 'any' type. + + +==== contextualTypingDiscriminantOverlap.ts (2 errors) ==== + type Handler = (value: T) => T; + type IndexedHandler = { + [key: string]: "b" | Handler<"b">; + value: Handler<"b">; + }; + type DeclaredOptionalHandler = { + [key: string]: "a" | "b" | undefined | Handler<"b">; + tag?: "a"; + value: Handler<"b">; + }; + type DeclaredRequiredHandler = { + [key: string]: "b" | Handler<"b">; + tag: "b"; + value: Handler<"b">; + }; + + const indexedOptional: + | { tag: "a"; value: Handler<"a"> } + | { tag?: "a"; value: Handler<"a"> } + | IndexedHandler = { + value: value => value, // error + ~~~~~ +!!! error TS7006: Parameter 'value' implicitly has an 'any' type. + }; + + const declaredOptional: + | { tag: "a"; value: Handler<"a"> } + | DeclaredOptionalHandler = { + value: value => value, + }; + + const declaredRequired: + | { tag: "a"; value: Handler<"a"> } + | DeclaredRequiredHandler = { + tag: "a", + value: value => value, + }; + + const indexedRequired: + | { tag: "a"; value: Handler<"a"> } + | IndexedHandler = { + value: value => value, // error + ~~~~~ +!!! error TS7006: Parameter 'value' implicitly has an 'any' type. + }; + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=false).symbols b/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=false).symbols new file mode 100644 index 0000000000000..1ecb836244621 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=false).symbols @@ -0,0 +1,133 @@ +//// [tests/cases/compiler/contextualTypingDiscriminantOverlap.ts] //// + +=== contextualTypingDiscriminantOverlap.ts === +type Handler = (value: T) => T; +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) +>T : Symbol(T, Decl(contextualTypingDiscriminantOverlap.ts, 0, 13)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 0, 19)) +>T : Symbol(T, Decl(contextualTypingDiscriminantOverlap.ts, 0, 13)) +>T : Symbol(T, Decl(contextualTypingDiscriminantOverlap.ts, 0, 13)) + +type IndexedHandler = { +>IndexedHandler : Symbol(IndexedHandler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 34)) + + [key: string]: "b" | Handler<"b">; +>key : Symbol(key, Decl(contextualTypingDiscriminantOverlap.ts, 2, 5)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + value: Handler<"b">; +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 2, 38)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + +}; +type DeclaredOptionalHandler = { +>DeclaredOptionalHandler : Symbol(DeclaredOptionalHandler, Decl(contextualTypingDiscriminantOverlap.ts, 4, 2)) + + [key: string]: "a" | "b" | undefined | Handler<"b">; +>key : Symbol(key, Decl(contextualTypingDiscriminantOverlap.ts, 6, 5)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + tag?: "a"; +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 6, 56)) + + value: Handler<"b">; +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 7, 14)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + +}; +type DeclaredRequiredHandler = { +>DeclaredRequiredHandler : Symbol(DeclaredRequiredHandler, Decl(contextualTypingDiscriminantOverlap.ts, 9, 2)) + + [key: string]: "b" | Handler<"b">; +>key : Symbol(key, Decl(contextualTypingDiscriminantOverlap.ts, 11, 5)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + tag: "b"; +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 11, 38)) + + value: Handler<"b">; +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 12, 13)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + +}; + +const indexedOptional: +>indexedOptional : Symbol(indexedOptional, Decl(contextualTypingDiscriminantOverlap.ts, 16, 5)) + + | { tag: "a"; value: Handler<"a"> } +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 17, 7)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 17, 17)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + | { tag?: "a"; value: Handler<"a"> } +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 18, 7)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 18, 18)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + | IndexedHandler = { +>IndexedHandler : Symbol(IndexedHandler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 34)) + + value: value => value, // error +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 19, 24)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 20, 14)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 20, 14)) + + }; + +const declaredOptional: +>declaredOptional : Symbol(declaredOptional, Decl(contextualTypingDiscriminantOverlap.ts, 23, 5)) + + | { tag: "a"; value: Handler<"a"> } +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 24, 7)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 24, 17)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + | DeclaredOptionalHandler = { +>DeclaredOptionalHandler : Symbol(DeclaredOptionalHandler, Decl(contextualTypingDiscriminantOverlap.ts, 4, 2)) + + value: value => value, +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 25, 33)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 26, 14)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 26, 14)) + + }; + +const declaredRequired: +>declaredRequired : Symbol(declaredRequired, Decl(contextualTypingDiscriminantOverlap.ts, 29, 5)) + + | { tag: "a"; value: Handler<"a"> } +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 30, 7)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 30, 17)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + | DeclaredRequiredHandler = { +>DeclaredRequiredHandler : Symbol(DeclaredRequiredHandler, Decl(contextualTypingDiscriminantOverlap.ts, 9, 2)) + + tag: "a", +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 31, 33)) + + value: value => value, +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 32, 17)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 33, 14)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 33, 14)) + + }; + +const indexedRequired: +>indexedRequired : Symbol(indexedRequired, Decl(contextualTypingDiscriminantOverlap.ts, 36, 5)) + + | { tag: "a"; value: Handler<"a"> } +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 37, 7)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 37, 17)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + | IndexedHandler = { +>IndexedHandler : Symbol(IndexedHandler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 34)) + + value: value => value, // error +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 38, 24)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 39, 14)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 39, 14)) + + }; + diff --git a/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=false).types b/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=false).types new file mode 100644 index 0000000000000..6cf5ad220eb7c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=false).types @@ -0,0 +1,124 @@ +//// [tests/cases/compiler/contextualTypingDiscriminantOverlap.ts] //// + +=== contextualTypingDiscriminantOverlap.ts === +type Handler = (value: T) => T; +>Handler : Handler +>value : T + +type IndexedHandler = { +>IndexedHandler : IndexedHandler + + [key: string]: "b" | Handler<"b">; +>key : string + + value: Handler<"b">; +>value : Handler<"b"> + +}; +type DeclaredOptionalHandler = { +>DeclaredOptionalHandler : DeclaredOptionalHandler + + [key: string]: "a" | "b" | undefined | Handler<"b">; +>key : string + + tag?: "a"; +>tag : "a" | undefined + + value: Handler<"b">; +>value : Handler<"b"> + +}; +type DeclaredRequiredHandler = { +>DeclaredRequiredHandler : DeclaredRequiredHandler + + [key: string]: "b" | Handler<"b">; +>key : string + + tag: "b"; +>tag : "b" + + value: Handler<"b">; +>value : Handler<"b"> + +}; + +const indexedOptional: +>indexedOptional : IndexedHandler | { tag: "a"; value: Handler<"a">; } | { tag?: "a"; value: Handler<"a">; } + + | { tag: "a"; value: Handler<"a"> } +>tag : "a" +>value : Handler<"a"> + + | { tag?: "a"; value: Handler<"a"> } +>tag : "a" | undefined +>value : Handler<"a"> + + | IndexedHandler = { +>{ value: value => value, // error } : { value: (value: any) => any; } + + value: value => value, // error +>value : (value: any) => any +>value => value : (value: any) => any +>value : any +>value : any + + }; + +const declaredOptional: +>declaredOptional : DeclaredOptionalHandler | { tag: "a"; value: Handler<"a">; } + + | { tag: "a"; value: Handler<"a"> } +>tag : "a" +>value : Handler<"a"> + + | DeclaredOptionalHandler = { +>{ value: value => value, } : { value: (value: "b") => "b"; } + + value: value => value, +>value : (value: "b") => "b" +>value => value : (value: "b") => "b" +>value : "b" +>value : "b" + + }; + +const declaredRequired: +>declaredRequired : DeclaredRequiredHandler | { tag: "a"; value: Handler<"a">; } + + | { tag: "a"; value: Handler<"a"> } +>tag : "a" +>value : Handler<"a"> + + | DeclaredRequiredHandler = { +>{ tag: "a", value: value => value, } : { tag: "a"; value: (value: "a") => "a"; } + + tag: "a", +>tag : "a" +>"a" : "a" + + value: value => value, +>value : (value: "a") => "a" +>value => value : (value: "a") => "a" +>value : "a" +>value : "a" + + }; + +const indexedRequired: +>indexedRequired : IndexedHandler | { tag: "a"; value: Handler<"a">; } + + | { tag: "a"; value: Handler<"a"> } +>tag : "a" +>value : Handler<"a"> + + | IndexedHandler = { +>{ value: value => value, // error } : { value: (value: any) => any; } + + value: value => value, // error +>value : (value: any) => any +>value => value : (value: any) => any +>value : any +>value : any + + }; + diff --git a/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=true).errors.txt b/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=true).errors.txt new file mode 100644 index 0000000000000..54dea5cbc919e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=true).errors.txt @@ -0,0 +1,51 @@ +contextualTypingDiscriminantOverlap.ts(21,16): error TS7006: Parameter 'value' implicitly has an 'any' type. +contextualTypingDiscriminantOverlap.ts(40,16): error TS7006: Parameter 'value' implicitly has an 'any' type. + + +==== contextualTypingDiscriminantOverlap.ts (2 errors) ==== + type Handler = (value: T) => T; + type IndexedHandler = { + [key: string]: "b" | Handler<"b">; + value: Handler<"b">; + }; + type DeclaredOptionalHandler = { + [key: string]: "a" | "b" | undefined | Handler<"b">; + tag?: "a"; + value: Handler<"b">; + }; + type DeclaredRequiredHandler = { + [key: string]: "b" | Handler<"b">; + tag: "b"; + value: Handler<"b">; + }; + + const indexedOptional: + | { tag: "a"; value: Handler<"a"> } + | { tag?: "a"; value: Handler<"a"> } + | IndexedHandler = { + value: value => value, // error + ~~~~~ +!!! error TS7006: Parameter 'value' implicitly has an 'any' type. + }; + + const declaredOptional: + | { tag: "a"; value: Handler<"a"> } + | DeclaredOptionalHandler = { + value: value => value, + }; + + const declaredRequired: + | { tag: "a"; value: Handler<"a"> } + | DeclaredRequiredHandler = { + tag: "a", + value: value => value, + }; + + const indexedRequired: + | { tag: "a"; value: Handler<"a"> } + | IndexedHandler = { + value: value => value, // error + ~~~~~ +!!! error TS7006: Parameter 'value' implicitly has an 'any' type. + }; + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=true).symbols b/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=true).symbols new file mode 100644 index 0000000000000..1ecb836244621 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=true).symbols @@ -0,0 +1,133 @@ +//// [tests/cases/compiler/contextualTypingDiscriminantOverlap.ts] //// + +=== contextualTypingDiscriminantOverlap.ts === +type Handler = (value: T) => T; +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) +>T : Symbol(T, Decl(contextualTypingDiscriminantOverlap.ts, 0, 13)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 0, 19)) +>T : Symbol(T, Decl(contextualTypingDiscriminantOverlap.ts, 0, 13)) +>T : Symbol(T, Decl(contextualTypingDiscriminantOverlap.ts, 0, 13)) + +type IndexedHandler = { +>IndexedHandler : Symbol(IndexedHandler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 34)) + + [key: string]: "b" | Handler<"b">; +>key : Symbol(key, Decl(contextualTypingDiscriminantOverlap.ts, 2, 5)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + value: Handler<"b">; +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 2, 38)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + +}; +type DeclaredOptionalHandler = { +>DeclaredOptionalHandler : Symbol(DeclaredOptionalHandler, Decl(contextualTypingDiscriminantOverlap.ts, 4, 2)) + + [key: string]: "a" | "b" | undefined | Handler<"b">; +>key : Symbol(key, Decl(contextualTypingDiscriminantOverlap.ts, 6, 5)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + tag?: "a"; +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 6, 56)) + + value: Handler<"b">; +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 7, 14)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + +}; +type DeclaredRequiredHandler = { +>DeclaredRequiredHandler : Symbol(DeclaredRequiredHandler, Decl(contextualTypingDiscriminantOverlap.ts, 9, 2)) + + [key: string]: "b" | Handler<"b">; +>key : Symbol(key, Decl(contextualTypingDiscriminantOverlap.ts, 11, 5)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + tag: "b"; +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 11, 38)) + + value: Handler<"b">; +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 12, 13)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + +}; + +const indexedOptional: +>indexedOptional : Symbol(indexedOptional, Decl(contextualTypingDiscriminantOverlap.ts, 16, 5)) + + | { tag: "a"; value: Handler<"a"> } +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 17, 7)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 17, 17)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + | { tag?: "a"; value: Handler<"a"> } +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 18, 7)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 18, 18)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + | IndexedHandler = { +>IndexedHandler : Symbol(IndexedHandler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 34)) + + value: value => value, // error +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 19, 24)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 20, 14)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 20, 14)) + + }; + +const declaredOptional: +>declaredOptional : Symbol(declaredOptional, Decl(contextualTypingDiscriminantOverlap.ts, 23, 5)) + + | { tag: "a"; value: Handler<"a"> } +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 24, 7)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 24, 17)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + | DeclaredOptionalHandler = { +>DeclaredOptionalHandler : Symbol(DeclaredOptionalHandler, Decl(contextualTypingDiscriminantOverlap.ts, 4, 2)) + + value: value => value, +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 25, 33)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 26, 14)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 26, 14)) + + }; + +const declaredRequired: +>declaredRequired : Symbol(declaredRequired, Decl(contextualTypingDiscriminantOverlap.ts, 29, 5)) + + | { tag: "a"; value: Handler<"a"> } +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 30, 7)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 30, 17)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + | DeclaredRequiredHandler = { +>DeclaredRequiredHandler : Symbol(DeclaredRequiredHandler, Decl(contextualTypingDiscriminantOverlap.ts, 9, 2)) + + tag: "a", +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 31, 33)) + + value: value => value, +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 32, 17)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 33, 14)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 33, 14)) + + }; + +const indexedRequired: +>indexedRequired : Symbol(indexedRequired, Decl(contextualTypingDiscriminantOverlap.ts, 36, 5)) + + | { tag: "a"; value: Handler<"a"> } +>tag : Symbol(tag, Decl(contextualTypingDiscriminantOverlap.ts, 37, 7)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 37, 17)) +>Handler : Symbol(Handler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 0)) + + | IndexedHandler = { +>IndexedHandler : Symbol(IndexedHandler, Decl(contextualTypingDiscriminantOverlap.ts, 0, 34)) + + value: value => value, // error +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 38, 24)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 39, 14)) +>value : Symbol(value, Decl(contextualTypingDiscriminantOverlap.ts, 39, 14)) + + }; + diff --git a/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=true).types b/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=true).types new file mode 100644 index 0000000000000..6cf5ad220eb7c --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/contextualTypingDiscriminantOverlap(exactoptionalpropertytypes=true).types @@ -0,0 +1,124 @@ +//// [tests/cases/compiler/contextualTypingDiscriminantOverlap.ts] //// + +=== contextualTypingDiscriminantOverlap.ts === +type Handler = (value: T) => T; +>Handler : Handler +>value : T + +type IndexedHandler = { +>IndexedHandler : IndexedHandler + + [key: string]: "b" | Handler<"b">; +>key : string + + value: Handler<"b">; +>value : Handler<"b"> + +}; +type DeclaredOptionalHandler = { +>DeclaredOptionalHandler : DeclaredOptionalHandler + + [key: string]: "a" | "b" | undefined | Handler<"b">; +>key : string + + tag?: "a"; +>tag : "a" | undefined + + value: Handler<"b">; +>value : Handler<"b"> + +}; +type DeclaredRequiredHandler = { +>DeclaredRequiredHandler : DeclaredRequiredHandler + + [key: string]: "b" | Handler<"b">; +>key : string + + tag: "b"; +>tag : "b" + + value: Handler<"b">; +>value : Handler<"b"> + +}; + +const indexedOptional: +>indexedOptional : IndexedHandler | { tag: "a"; value: Handler<"a">; } | { tag?: "a"; value: Handler<"a">; } + + | { tag: "a"; value: Handler<"a"> } +>tag : "a" +>value : Handler<"a"> + + | { tag?: "a"; value: Handler<"a"> } +>tag : "a" | undefined +>value : Handler<"a"> + + | IndexedHandler = { +>{ value: value => value, // error } : { value: (value: any) => any; } + + value: value => value, // error +>value : (value: any) => any +>value => value : (value: any) => any +>value : any +>value : any + + }; + +const declaredOptional: +>declaredOptional : DeclaredOptionalHandler | { tag: "a"; value: Handler<"a">; } + + | { tag: "a"; value: Handler<"a"> } +>tag : "a" +>value : Handler<"a"> + + | DeclaredOptionalHandler = { +>{ value: value => value, } : { value: (value: "b") => "b"; } + + value: value => value, +>value : (value: "b") => "b" +>value => value : (value: "b") => "b" +>value : "b" +>value : "b" + + }; + +const declaredRequired: +>declaredRequired : DeclaredRequiredHandler | { tag: "a"; value: Handler<"a">; } + + | { tag: "a"; value: Handler<"a"> } +>tag : "a" +>value : Handler<"a"> + + | DeclaredRequiredHandler = { +>{ tag: "a", value: value => value, } : { tag: "a"; value: (value: "a") => "a"; } + + tag: "a", +>tag : "a" +>"a" : "a" + + value: value => value, +>value : (value: "a") => "a" +>value => value : (value: "a") => "a" +>value : "a" +>value : "a" + + }; + +const indexedRequired: +>indexedRequired : IndexedHandler | { tag: "a"; value: Handler<"a">; } + + | { tag: "a"; value: Handler<"a"> } +>tag : "a" +>value : Handler<"a"> + + | IndexedHandler = { +>{ value: value => value, // error } : { value: (value: any) => any; } + + value: value => value, // error +>value : (value: any) => any +>value => value : (value: any) => any +>value : any +>value : any + + }; + diff --git a/tsc/testdata/baselines/reference/compiler/discriminatedUnionInferenceClassHierarchies.errors.txt b/tsc/testdata/baselines/reference/compiler/discriminatedUnionInferenceClassHierarchies.errors.txt new file mode 100644 index 0000000000000..ba9204c25704f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/discriminatedUnionInferenceClassHierarchies.errors.txt @@ -0,0 +1,91 @@ +discriminatedUnionInferenceClassHierarchies.ts(19,33): error TS2345: Argument of type 'typeof Fail' is not assignable to parameter of type 'GlobalControllerClass<{ bar: any; }, { baz: any; }> | LocalControllerClass<{ bar: any; }, { baz: any; }>'. + Type 'typeof Fail' is not assignable to type 'GlobalControllerClass<{ bar: any; }, { baz: any; }>'. + Type 'Fail' is not assignable to type 'GlobalController<{ bar: any; }, { baz: any; }>'. + Types of property 'isLocal' are incompatible. + Type 'true' is not assignable to type 'false'. +discriminatedUnionInferenceClassHierarchies.ts(41,43): error TS2345: Argument of type 'typeof Fail' is not assignable to parameter of type 'ControllerClass<{ bar: any; }, { bar: any; }, { baz: any; }>'. + Type 'typeof Fail' is not assignable to type 'GlobalStoreControllerClass<{ bar: any; }, { bar: any; }, { baz: any; }>'. + Type 'Fail' is not assignable to type 'GlobalStoreController<{ bar: any; }, { bar: any; }, { baz: any; }>'. + Types of property 'isLocal' are incompatible. + Type 'true' is not assignable to type 'false'. + + +==== discriminatedUnionInferenceClassHierarchies.ts (2 errors) ==== + // The discriminant lives on the instance type behind a construct signature. + declare class GlobalController { + isLocal: false; + getProps(state: S, props: P): void; + } + declare class LocalController { + isLocal: true; + getProps(props: P, state: S): void; + } + interface GlobalControllerClass { + new (): GlobalController; + } + interface LocalControllerClass { + new (): LocalController; + } + declare function createEnhancer(Wrapper: GlobalControllerClass | LocalControllerClass): [P, S]; + + class Fail extends LocalController<{ baz: any }, { bar: any }> {} + const enhanced = createEnhancer(Fail); + ~~~~ +!!! error TS2345: Argument of type 'typeof Fail' is not assignable to parameter of type 'GlobalControllerClass<{ bar: any; }, { baz: any; }> | LocalControllerClass<{ bar: any; }, { baz: any; }>'. +!!! error TS2345: Type 'typeof Fail' is not assignable to type 'GlobalControllerClass<{ bar: any; }, { baz: any; }>'. +!!! error TS2345: Type 'Fail' is not assignable to type 'GlobalController<{ bar: any; }, { baz: any; }>'. +!!! error TS2345: Types of property 'isLocal' are incompatible. +!!! error TS2345: Type 'true' is not assignable to type 'false'. + + class WorkaroundUnusedMethod extends LocalController<{ baz: any }, { bar: any }> { + _unused() {} + } + const enhancedUnusedMethod = createEnhancer(WorkaroundUnusedMethod); + + class WorkaroundChangeSignature extends LocalController<{ baz: any }, { bar: any }> { + getProps(props: { baz: any }) {} + } + const enhancedChangedSignature = createEnhancer(WorkaroundChangeSignature); + + // Three type parameters with a default, as in the original report. + declare abstract class GlobalStoreController { + isLocal: false; + abstract getProps(storeState: SS, props: P, state: S): void; + } + interface GlobalStoreControllerClass { + new (): GlobalStoreController; + } + type ControllerClass = GlobalStoreControllerClass | LocalControllerClass; + declare function createStoreEnhancer(Wrapper: ControllerClass): [P, S, SS]; + const storeEnhanced = createStoreEnhancer(Fail); + ~~~~ +!!! error TS2345: Argument of type 'typeof Fail' is not assignable to parameter of type 'ControllerClass<{ bar: any; }, { bar: any; }, { baz: any; }>'. +!!! error TS2345: Type 'typeof Fail' is not assignable to type 'GlobalStoreControllerClass<{ bar: any; }, { bar: any; }, { baz: any; }>'. +!!! error TS2345: Type 'Fail' is not assignable to type 'GlobalStoreController<{ bar: any; }, { bar: any; }, { baz: any; }>'. +!!! error TS2345: Types of property 'isLocal' are incompatible. +!!! error TS2345: Type 'true' is not assignable to type 'false'. + + // Instances declared directly, through an alias, and through an extending interface. + interface Local { + isLocal: true; + a: T; + b: U; + } + interface NotLocal { + isLocal: false; + a: U; + b: T; + } + declare function callme(Wrapper: NotLocal | Local): [T, U]; + + declare const directDecl: Local; + const direct = callme(directDecl); + + type LocalStringNumberAlias = Local; + declare const typeAlias: LocalStringNumberAlias; + const alias = callme(typeAlias); + + interface LocalStringNumberInterface extends Local {} + declare const interfaceDecl: LocalStringNumberInterface; + const extended = callme(interfaceDecl); + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/discriminatedUnionInferenceClassHierarchies.symbols b/tsc/testdata/baselines/reference/compiler/discriminatedUnionInferenceClassHierarchies.symbols new file mode 100644 index 0000000000000..c166b235593c3 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/discriminatedUnionInferenceClassHierarchies.symbols @@ -0,0 +1,254 @@ +//// [tests/cases/compiler/discriminatedUnionInferenceClassHierarchies.ts] //// + +=== discriminatedUnionInferenceClassHierarchies.ts === +// The discriminant lives on the instance type behind a construct signature. +declare class GlobalController { +>GlobalController : Symbol(GlobalController, Decl(discriminatedUnionInferenceClassHierarchies.ts, 0, 0)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 1, 31)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 1, 33)) + + isLocal: false; +>isLocal : Symbol(GlobalController.isLocal, Decl(discriminatedUnionInferenceClassHierarchies.ts, 1, 38)) + + getProps(state: S, props: P): void; +>getProps : Symbol(GlobalController.getProps, Decl(discriminatedUnionInferenceClassHierarchies.ts, 2, 19)) +>state : Symbol(state, Decl(discriminatedUnionInferenceClassHierarchies.ts, 3, 13)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 1, 33)) +>props : Symbol(props, Decl(discriminatedUnionInferenceClassHierarchies.ts, 3, 22)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 1, 31)) +} +declare class LocalController { +>LocalController : Symbol(LocalController, Decl(discriminatedUnionInferenceClassHierarchies.ts, 4, 1)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 5, 30)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 5, 32)) + + isLocal: true; +>isLocal : Symbol(LocalController.isLocal, Decl(discriminatedUnionInferenceClassHierarchies.ts, 5, 37)) + + getProps(props: P, state: S): void; +>getProps : Symbol(LocalController.getProps, Decl(discriminatedUnionInferenceClassHierarchies.ts, 6, 18)) +>props : Symbol(props, Decl(discriminatedUnionInferenceClassHierarchies.ts, 7, 13)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 5, 30)) +>state : Symbol(state, Decl(discriminatedUnionInferenceClassHierarchies.ts, 7, 22)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 5, 32)) +} +interface GlobalControllerClass { +>GlobalControllerClass : Symbol(GlobalControllerClass, Decl(discriminatedUnionInferenceClassHierarchies.ts, 8, 1)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 9, 32)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 9, 34)) + + new (): GlobalController; +>GlobalController : Symbol(GlobalController, Decl(discriminatedUnionInferenceClassHierarchies.ts, 0, 0)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 9, 32)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 9, 34)) +} +interface LocalControllerClass { +>LocalControllerClass : Symbol(LocalControllerClass, Decl(discriminatedUnionInferenceClassHierarchies.ts, 11, 1)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 12, 31)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 12, 33)) + + new (): LocalController; +>LocalController : Symbol(LocalController, Decl(discriminatedUnionInferenceClassHierarchies.ts, 4, 1)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 12, 31)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 12, 33)) +} +declare function createEnhancer(Wrapper: GlobalControllerClass | LocalControllerClass): [P, S]; +>createEnhancer : Symbol(createEnhancer, Decl(discriminatedUnionInferenceClassHierarchies.ts, 14, 1)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 15, 32)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 15, 34)) +>Wrapper : Symbol(Wrapper, Decl(discriminatedUnionInferenceClassHierarchies.ts, 15, 38)) +>GlobalControllerClass : Symbol(GlobalControllerClass, Decl(discriminatedUnionInferenceClassHierarchies.ts, 8, 1)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 15, 32)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 15, 34)) +>LocalControllerClass : Symbol(LocalControllerClass, Decl(discriminatedUnionInferenceClassHierarchies.ts, 11, 1)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 15, 32)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 15, 34)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 15, 32)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 15, 34)) + +class Fail extends LocalController<{ baz: any }, { bar: any }> {} +>Fail : Symbol(Fail, Decl(discriminatedUnionInferenceClassHierarchies.ts, 15, 113)) +>LocalController : Symbol(LocalController, Decl(discriminatedUnionInferenceClassHierarchies.ts, 4, 1)) +>baz : Symbol(baz, Decl(discriminatedUnionInferenceClassHierarchies.ts, 17, 36)) +>bar : Symbol(bar, Decl(discriminatedUnionInferenceClassHierarchies.ts, 17, 50)) + +const enhanced = createEnhancer(Fail); +>enhanced : Symbol(enhanced, Decl(discriminatedUnionInferenceClassHierarchies.ts, 18, 5)) +>createEnhancer : Symbol(createEnhancer, Decl(discriminatedUnionInferenceClassHierarchies.ts, 14, 1)) +>Fail : Symbol(Fail, Decl(discriminatedUnionInferenceClassHierarchies.ts, 15, 113)) + +class WorkaroundUnusedMethod extends LocalController<{ baz: any }, { bar: any }> { +>WorkaroundUnusedMethod : Symbol(WorkaroundUnusedMethod, Decl(discriminatedUnionInferenceClassHierarchies.ts, 18, 38)) +>LocalController : Symbol(LocalController, Decl(discriminatedUnionInferenceClassHierarchies.ts, 4, 1)) +>baz : Symbol(baz, Decl(discriminatedUnionInferenceClassHierarchies.ts, 20, 54)) +>bar : Symbol(bar, Decl(discriminatedUnionInferenceClassHierarchies.ts, 20, 68)) + + _unused() {} +>_unused : Symbol(WorkaroundUnusedMethod._unused, Decl(discriminatedUnionInferenceClassHierarchies.ts, 20, 82)) +} +const enhancedUnusedMethod = createEnhancer(WorkaroundUnusedMethod); +>enhancedUnusedMethod : Symbol(enhancedUnusedMethod, Decl(discriminatedUnionInferenceClassHierarchies.ts, 23, 5)) +>createEnhancer : Symbol(createEnhancer, Decl(discriminatedUnionInferenceClassHierarchies.ts, 14, 1)) +>WorkaroundUnusedMethod : Symbol(WorkaroundUnusedMethod, Decl(discriminatedUnionInferenceClassHierarchies.ts, 18, 38)) + +class WorkaroundChangeSignature extends LocalController<{ baz: any }, { bar: any }> { +>WorkaroundChangeSignature : Symbol(WorkaroundChangeSignature, Decl(discriminatedUnionInferenceClassHierarchies.ts, 23, 68)) +>LocalController : Symbol(LocalController, Decl(discriminatedUnionInferenceClassHierarchies.ts, 4, 1)) +>baz : Symbol(baz, Decl(discriminatedUnionInferenceClassHierarchies.ts, 25, 57)) +>bar : Symbol(bar, Decl(discriminatedUnionInferenceClassHierarchies.ts, 25, 71)) + + getProps(props: { baz: any }) {} +>getProps : Symbol(WorkaroundChangeSignature.getProps, Decl(discriminatedUnionInferenceClassHierarchies.ts, 25, 85)) +>props : Symbol(props, Decl(discriminatedUnionInferenceClassHierarchies.ts, 26, 13)) +>baz : Symbol(baz, Decl(discriminatedUnionInferenceClassHierarchies.ts, 26, 21)) +} +const enhancedChangedSignature = createEnhancer(WorkaroundChangeSignature); +>enhancedChangedSignature : Symbol(enhancedChangedSignature, Decl(discriminatedUnionInferenceClassHierarchies.ts, 28, 5)) +>createEnhancer : Symbol(createEnhancer, Decl(discriminatedUnionInferenceClassHierarchies.ts, 14, 1)) +>WorkaroundChangeSignature : Symbol(WorkaroundChangeSignature, Decl(discriminatedUnionInferenceClassHierarchies.ts, 23, 68)) + +// Three type parameters with a default, as in the original report. +declare abstract class GlobalStoreController { +>GlobalStoreController : Symbol(GlobalStoreController, Decl(discriminatedUnionInferenceClassHierarchies.ts, 28, 75)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 31, 45)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 31, 47)) +>SS : Symbol(SS, Decl(discriminatedUnionInferenceClassHierarchies.ts, 31, 50)) + + isLocal: false; +>isLocal : Symbol(GlobalStoreController.isLocal, Decl(discriminatedUnionInferenceClassHierarchies.ts, 31, 56)) + + abstract getProps(storeState: SS, props: P, state: S): void; +>getProps : Symbol(GlobalStoreController.getProps, Decl(discriminatedUnionInferenceClassHierarchies.ts, 32, 19)) +>storeState : Symbol(storeState, Decl(discriminatedUnionInferenceClassHierarchies.ts, 33, 22)) +>SS : Symbol(SS, Decl(discriminatedUnionInferenceClassHierarchies.ts, 31, 50)) +>props : Symbol(props, Decl(discriminatedUnionInferenceClassHierarchies.ts, 33, 37)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 31, 45)) +>state : Symbol(state, Decl(discriminatedUnionInferenceClassHierarchies.ts, 33, 47)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 31, 47)) +} +interface GlobalStoreControllerClass { +>GlobalStoreControllerClass : Symbol(GlobalStoreControllerClass, Decl(discriminatedUnionInferenceClassHierarchies.ts, 34, 1)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 35, 37)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 35, 39)) +>SS : Symbol(SS, Decl(discriminatedUnionInferenceClassHierarchies.ts, 35, 42)) + + new (): GlobalStoreController; +>GlobalStoreController : Symbol(GlobalStoreController, Decl(discriminatedUnionInferenceClassHierarchies.ts, 28, 75)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 35, 37)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 35, 39)) +>SS : Symbol(SS, Decl(discriminatedUnionInferenceClassHierarchies.ts, 35, 42)) +} +type ControllerClass = GlobalStoreControllerClass | LocalControllerClass; +>ControllerClass : Symbol(ControllerClass, Decl(discriminatedUnionInferenceClassHierarchies.ts, 37, 1)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 38, 21)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 38, 23)) +>SS : Symbol(SS, Decl(discriminatedUnionInferenceClassHierarchies.ts, 38, 26)) +>GlobalStoreControllerClass : Symbol(GlobalStoreControllerClass, Decl(discriminatedUnionInferenceClassHierarchies.ts, 34, 1)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 38, 21)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 38, 23)) +>SS : Symbol(SS, Decl(discriminatedUnionInferenceClassHierarchies.ts, 38, 26)) +>LocalControllerClass : Symbol(LocalControllerClass, Decl(discriminatedUnionInferenceClassHierarchies.ts, 11, 1)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 38, 21)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 38, 23)) + +declare function createStoreEnhancer(Wrapper: ControllerClass): [P, S, SS]; +>createStoreEnhancer : Symbol(createStoreEnhancer, Decl(discriminatedUnionInferenceClassHierarchies.ts, 38, 104)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 39, 37)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 39, 39)) +>SS : Symbol(SS, Decl(discriminatedUnionInferenceClassHierarchies.ts, 39, 42)) +>Wrapper : Symbol(Wrapper, Decl(discriminatedUnionInferenceClassHierarchies.ts, 39, 54)) +>ControllerClass : Symbol(ControllerClass, Decl(discriminatedUnionInferenceClassHierarchies.ts, 37, 1)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 39, 37)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 39, 39)) +>SS : Symbol(SS, Decl(discriminatedUnionInferenceClassHierarchies.ts, 39, 42)) +>P : Symbol(P, Decl(discriminatedUnionInferenceClassHierarchies.ts, 39, 37)) +>S : Symbol(S, Decl(discriminatedUnionInferenceClassHierarchies.ts, 39, 39)) +>SS : Symbol(SS, Decl(discriminatedUnionInferenceClassHierarchies.ts, 39, 42)) + +const storeEnhanced = createStoreEnhancer(Fail); +>storeEnhanced : Symbol(storeEnhanced, Decl(discriminatedUnionInferenceClassHierarchies.ts, 40, 5)) +>createStoreEnhancer : Symbol(createStoreEnhancer, Decl(discriminatedUnionInferenceClassHierarchies.ts, 38, 104)) +>Fail : Symbol(Fail, Decl(discriminatedUnionInferenceClassHierarchies.ts, 15, 113)) + +// Instances declared directly, through an alias, and through an extending interface. +interface Local { +>Local : Symbol(Local, Decl(discriminatedUnionInferenceClassHierarchies.ts, 40, 48)) +>T : Symbol(T, Decl(discriminatedUnionInferenceClassHierarchies.ts, 43, 16)) +>U : Symbol(U, Decl(discriminatedUnionInferenceClassHierarchies.ts, 43, 18)) + + isLocal: true; +>isLocal : Symbol(Local.isLocal, Decl(discriminatedUnionInferenceClassHierarchies.ts, 43, 23)) + + a: T; +>a : Symbol(Local.a, Decl(discriminatedUnionInferenceClassHierarchies.ts, 44, 18)) +>T : Symbol(T, Decl(discriminatedUnionInferenceClassHierarchies.ts, 43, 16)) + + b: U; +>b : Symbol(Local.b, Decl(discriminatedUnionInferenceClassHierarchies.ts, 45, 9)) +>U : Symbol(U, Decl(discriminatedUnionInferenceClassHierarchies.ts, 43, 18)) +} +interface NotLocal { +>NotLocal : Symbol(NotLocal, Decl(discriminatedUnionInferenceClassHierarchies.ts, 47, 1)) +>T : Symbol(T, Decl(discriminatedUnionInferenceClassHierarchies.ts, 48, 19)) +>U : Symbol(U, Decl(discriminatedUnionInferenceClassHierarchies.ts, 48, 21)) + + isLocal: false; +>isLocal : Symbol(NotLocal.isLocal, Decl(discriminatedUnionInferenceClassHierarchies.ts, 48, 26)) + + a: U; +>a : Symbol(NotLocal.a, Decl(discriminatedUnionInferenceClassHierarchies.ts, 49, 19)) +>U : Symbol(U, Decl(discriminatedUnionInferenceClassHierarchies.ts, 48, 21)) + + b: T; +>b : Symbol(NotLocal.b, Decl(discriminatedUnionInferenceClassHierarchies.ts, 50, 9)) +>T : Symbol(T, Decl(discriminatedUnionInferenceClassHierarchies.ts, 48, 19)) +} +declare function callme(Wrapper: NotLocal | Local): [T, U]; +>callme : Symbol(callme, Decl(discriminatedUnionInferenceClassHierarchies.ts, 52, 1)) +>T : Symbol(T, Decl(discriminatedUnionInferenceClassHierarchies.ts, 53, 24)) +>U : Symbol(U, Decl(discriminatedUnionInferenceClassHierarchies.ts, 53, 26)) +>Wrapper : Symbol(Wrapper, Decl(discriminatedUnionInferenceClassHierarchies.ts, 53, 30)) +>NotLocal : Symbol(NotLocal, Decl(discriminatedUnionInferenceClassHierarchies.ts, 47, 1)) +>T : Symbol(T, Decl(discriminatedUnionInferenceClassHierarchies.ts, 53, 24)) +>U : Symbol(U, Decl(discriminatedUnionInferenceClassHierarchies.ts, 53, 26)) +>Local : Symbol(Local, Decl(discriminatedUnionInferenceClassHierarchies.ts, 40, 48)) +>T : Symbol(T, Decl(discriminatedUnionInferenceClassHierarchies.ts, 53, 24)) +>U : Symbol(U, Decl(discriminatedUnionInferenceClassHierarchies.ts, 53, 26)) +>T : Symbol(T, Decl(discriminatedUnionInferenceClassHierarchies.ts, 53, 24)) +>U : Symbol(U, Decl(discriminatedUnionInferenceClassHierarchies.ts, 53, 26)) + +declare const directDecl: Local; +>directDecl : Symbol(directDecl, Decl(discriminatedUnionInferenceClassHierarchies.ts, 55, 13)) +>Local : Symbol(Local, Decl(discriminatedUnionInferenceClassHierarchies.ts, 40, 48)) + +const direct = callme(directDecl); +>direct : Symbol(direct, Decl(discriminatedUnionInferenceClassHierarchies.ts, 56, 5)) +>callme : Symbol(callme, Decl(discriminatedUnionInferenceClassHierarchies.ts, 52, 1)) +>directDecl : Symbol(directDecl, Decl(discriminatedUnionInferenceClassHierarchies.ts, 55, 13)) + +type LocalStringNumberAlias = Local; +>LocalStringNumberAlias : Symbol(LocalStringNumberAlias, Decl(discriminatedUnionInferenceClassHierarchies.ts, 56, 34)) +>Local : Symbol(Local, Decl(discriminatedUnionInferenceClassHierarchies.ts, 40, 48)) + +declare const typeAlias: LocalStringNumberAlias; +>typeAlias : Symbol(typeAlias, Decl(discriminatedUnionInferenceClassHierarchies.ts, 59, 13)) +>LocalStringNumberAlias : Symbol(LocalStringNumberAlias, Decl(discriminatedUnionInferenceClassHierarchies.ts, 56, 34)) + +const alias = callme(typeAlias); +>alias : Symbol(alias, Decl(discriminatedUnionInferenceClassHierarchies.ts, 60, 5)) +>callme : Symbol(callme, Decl(discriminatedUnionInferenceClassHierarchies.ts, 52, 1)) +>typeAlias : Symbol(typeAlias, Decl(discriminatedUnionInferenceClassHierarchies.ts, 59, 13)) + +interface LocalStringNumberInterface extends Local {} +>LocalStringNumberInterface : Symbol(LocalStringNumberInterface, Decl(discriminatedUnionInferenceClassHierarchies.ts, 60, 32)) +>Local : Symbol(Local, Decl(discriminatedUnionInferenceClassHierarchies.ts, 40, 48)) + +declare const interfaceDecl: LocalStringNumberInterface; +>interfaceDecl : Symbol(interfaceDecl, Decl(discriminatedUnionInferenceClassHierarchies.ts, 63, 13)) +>LocalStringNumberInterface : Symbol(LocalStringNumberInterface, Decl(discriminatedUnionInferenceClassHierarchies.ts, 60, 32)) + +const extended = callme(interfaceDecl); +>extended : Symbol(extended, Decl(discriminatedUnionInferenceClassHierarchies.ts, 64, 5)) +>callme : Symbol(callme, Decl(discriminatedUnionInferenceClassHierarchies.ts, 52, 1)) +>interfaceDecl : Symbol(interfaceDecl, Decl(discriminatedUnionInferenceClassHierarchies.ts, 63, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/discriminatedUnionInferenceClassHierarchies.types b/tsc/testdata/baselines/reference/compiler/discriminatedUnionInferenceClassHierarchies.types new file mode 100644 index 0000000000000..cf333038520e3 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/discriminatedUnionInferenceClassHierarchies.types @@ -0,0 +1,170 @@ +//// [tests/cases/compiler/discriminatedUnionInferenceClassHierarchies.ts] //// + +=== discriminatedUnionInferenceClassHierarchies.ts === +// The discriminant lives on the instance type behind a construct signature. +declare class GlobalController { +>GlobalController : GlobalController + + isLocal: false; +>isLocal : false +>false : false + + getProps(state: S, props: P): void; +>getProps : (state: S, props: P) => void +>state : S +>props : P +} +declare class LocalController { +>LocalController : LocalController + + isLocal: true; +>isLocal : true +>true : true + + getProps(props: P, state: S): void; +>getProps : (props: P, state: S) => void +>props : P +>state : S +} +interface GlobalControllerClass { + new (): GlobalController; +} +interface LocalControllerClass { + new (): LocalController; +} +declare function createEnhancer(Wrapper: GlobalControllerClass | LocalControllerClass): [P, S]; +>createEnhancer : (Wrapper: GlobalControllerClass | LocalControllerClass) => [P, S] +>Wrapper : GlobalControllerClass | LocalControllerClass + +class Fail extends LocalController<{ baz: any }, { bar: any }> {} +>Fail : Fail +>LocalController : LocalController<{ baz: any; }, { bar: any; }> +>baz : any +>bar : any + +const enhanced = createEnhancer(Fail); +>enhanced : [{ bar: any; }, { baz: any; }] +>createEnhancer(Fail) : [{ bar: any; }, { baz: any; }] +>createEnhancer : (Wrapper: GlobalControllerClass | LocalControllerClass) => [P, S] +>Fail : typeof Fail + +class WorkaroundUnusedMethod extends LocalController<{ baz: any }, { bar: any }> { +>WorkaroundUnusedMethod : WorkaroundUnusedMethod +>LocalController : LocalController<{ baz: any; }, { bar: any; }> +>baz : any +>bar : any + + _unused() {} +>_unused : () => void +} +const enhancedUnusedMethod = createEnhancer(WorkaroundUnusedMethod); +>enhancedUnusedMethod : [{ baz: any; }, { bar: any; }] +>createEnhancer(WorkaroundUnusedMethod) : [{ baz: any; }, { bar: any; }] +>createEnhancer : (Wrapper: GlobalControllerClass | LocalControllerClass) => [P, S] +>WorkaroundUnusedMethod : typeof WorkaroundUnusedMethod + +class WorkaroundChangeSignature extends LocalController<{ baz: any }, { bar: any }> { +>WorkaroundChangeSignature : WorkaroundChangeSignature +>LocalController : LocalController<{ baz: any; }, { bar: any; }> +>baz : any +>bar : any + + getProps(props: { baz: any }) {} +>getProps : (props: { baz: any; }) => void +>props : { baz: any; } +>baz : any +} +const enhancedChangedSignature = createEnhancer(WorkaroundChangeSignature); +>enhancedChangedSignature : [{ baz: any; }, { baz: any; }] +>createEnhancer(WorkaroundChangeSignature) : [{ baz: any; }, { baz: any; }] +>createEnhancer : (Wrapper: GlobalControllerClass | LocalControllerClass) => [P, S] +>WorkaroundChangeSignature : typeof WorkaroundChangeSignature + +// Three type parameters with a default, as in the original report. +declare abstract class GlobalStoreController { +>GlobalStoreController : GlobalStoreController + + isLocal: false; +>isLocal : false +>false : false + + abstract getProps(storeState: SS, props: P, state: S): void; +>getProps : (storeState: SS, props: P, state: S) => void +>storeState : SS +>props : P +>state : S +} +interface GlobalStoreControllerClass { + new (): GlobalStoreController; +} +type ControllerClass = GlobalStoreControllerClass | LocalControllerClass; +>ControllerClass : ControllerClass + +declare function createStoreEnhancer(Wrapper: ControllerClass): [P, S, SS]; +>createStoreEnhancer : (Wrapper: ControllerClass) => [P, S, SS] +>Wrapper : ControllerClass + +const storeEnhanced = createStoreEnhancer(Fail); +>storeEnhanced : [{ bar: any; }, { bar: any; }, { baz: any; }] +>createStoreEnhancer(Fail) : [{ bar: any; }, { bar: any; }, { baz: any; }] +>createStoreEnhancer : (Wrapper: ControllerClass) => [P, S, SS] +>Fail : typeof Fail + +// Instances declared directly, through an alias, and through an extending interface. +interface Local { + isLocal: true; +>isLocal : true +>true : true + + a: T; +>a : T + + b: U; +>b : U +} +interface NotLocal { + isLocal: false; +>isLocal : false +>false : false + + a: U; +>a : U + + b: T; +>b : T +} +declare function callme(Wrapper: NotLocal | Local): [T, U]; +>callme : (Wrapper: NotLocal | Local) => [T, U] +>Wrapper : Local | NotLocal + +declare const directDecl: Local; +>directDecl : Local + +const direct = callme(directDecl); +>direct : [string, number] +>callme(directDecl) : [string, number] +>callme : (Wrapper: NotLocal | Local) => [T, U] +>directDecl : Local + +type LocalStringNumberAlias = Local; +>LocalStringNumberAlias : LocalStringNumberAlias + +declare const typeAlias: LocalStringNumberAlias; +>typeAlias : LocalStringNumberAlias + +const alias = callme(typeAlias); +>alias : [string, number] +>callme(typeAlias) : [string, number] +>callme : (Wrapper: NotLocal | Local) => [T, U] +>typeAlias : LocalStringNumberAlias + +interface LocalStringNumberInterface extends Local {} +declare const interfaceDecl: LocalStringNumberInterface; +>interfaceDecl : LocalStringNumberInterface + +const extended = callme(interfaceDecl); +>extended : [string, number] +>callme(interfaceDecl) : [string, number] +>callme : (Wrapper: NotLocal | Local) => [T, U] +>interfaceDecl : LocalStringNumberInterface + diff --git a/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=false).errors.txt b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=false).errors.txt new file mode 100644 index 0000000000000..dc3fa84ee0773 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=false).errors.txt @@ -0,0 +1,159 @@ +inferenceDiscriminantOverlap.ts(23,43): error TS2345: Argument of type '{ tag: "a"; value: 1; } | { tag?: "b" | undefined; value: 2; }' is not assignable to parameter of type '{ tag?: "a" | undefined; value: 1 | 2; }'. + Type '{ tag?: "b" | undefined; value: 2; }' is not assignable to type '{ tag?: "a" | undefined; value: 1 | 2; }'. + Types of property 'tag' are incompatible. + Type '"b" | undefined' is not assignable to type '"a" | undefined'. + Type '"b"' is not assignable to type '"a"'. +inferenceDiscriminantOverlap.ts(24,46): error TS2345: Argument of type '{ tag: "a"; value: 1; } | { tag?: "a" | undefined; value: 2; } | { tag: "b"; value: 3; }' is not assignable to parameter of type '{ tag?: "a" | undefined; value: 1 | 2; }'. + Type '{ tag: "b"; value: 3; }' is not assignable to type '{ tag?: "a" | undefined; value: 1 | 2; }'. + Types of property 'tag' are incompatible. + Type '"b"' is not assignable to type '"a"'. +inferenceDiscriminantOverlap.ts(25,46): error TS2345: Argument of type '{ tag: "a"; value: 1; } | { tag: "b"; value: 2; }' is not assignable to parameter of type '{ tag?: "a" | undefined; value: 1; }'. + Type '{ tag: "b"; value: 2; }' is not assignable to type '{ tag?: "a" | undefined; value: 1; }'. + Types of property 'tag' are incompatible. + Type '"b"' is not assignable to type '"a"'. +inferenceDiscriminantOverlap.ts(27,47): error TS2345: Argument of type '{ tag: "a"; value: 1; } | { tag: "b" | undefined; value: 2; }' is not assignable to parameter of type '{ tag?: "a" | undefined; value: 1 | 2; }'. + Type '{ tag: "b" | undefined; value: 2; }' is not assignable to type '{ tag?: "a" | undefined; value: 1 | 2; }'. + Types of property 'tag' are incompatible. + Type '"b" | undefined' is not assignable to type '"a" | undefined'. + Type '"b"' is not assignable to type '"a"'. +inferenceDiscriminantOverlap.ts(31,46): error TS2345: Argument of type '{ tag: "a"; value: "a"; } | { [key: string]: "b"; tag: "b"; value: "b"; }' is not assignable to parameter of type '{ tag?: "a" | undefined; value: "a"; }'. + Type '{ [key: string]: "b"; tag: "b"; value: "b"; }' is not assignable to type '{ tag?: "a" | undefined; value: "a"; }'. + Types of property 'tag' are incompatible. + Type '"b"' is not assignable to type '"a"'. +inferenceDiscriminantOverlap.ts(34,47): error TS2345: Argument of type '{ tag: "a" | "b"; value: 1; } | { tag: "b"; value: 2; }' is not assignable to parameter of type '{ tag: "a"; value: 1; }'. + Type '{ tag: "a" | "b"; value: 1; }' is not assignable to type '{ tag: "a"; value: 1; }'. + Types of property 'tag' are incompatible. + Type '"a" | "b"' is not assignable to type '"a"'. + Type '"b"' is not assignable to type '"a"'. +inferenceDiscriminantOverlap.ts(35,45): error TS2345: Argument of type '{ tag: "a"; value: "a"; } | { tag?: "a" | undefined; value: "a"; } | { [key: string]: "b"; value: "b"; }' is not assignable to parameter of type '{ tag: "a"; value: "a"; }'. + Type '{ tag?: "a" | undefined; value: "a"; }' is not assignable to type '{ tag: "a"; value: "a"; }'. + Types of property 'tag' are incompatible. + Type '"a" | undefined' is not assignable to type '"a"'. + Type 'undefined' is not assignable to type '"a"'. +inferenceDiscriminantOverlap.ts(39,5): error TS2322: Type '{ tag?: "a" | undefined; value: 1 | 2; }' is not assignable to type '{ tag: "a"; value: 1; } | { tag?: "b" | undefined; value: 2; }'. + Type '{ tag?: "a" | undefined; value: 1 | 2; }' is not assignable to type '{ tag?: "b" | undefined; value: 2; }'. + Types of property 'tag' are incompatible. + Type '"a" | undefined' is not assignable to type '"b" | undefined'. + Type '"a"' is not assignable to type '"b"'. + + +==== inferenceDiscriminantOverlap.ts (8 errors) ==== + declare const validOptionalSource: { tag: "a"; value: 1 } | { tag?: "a"; value: 2 }; + declare const mixedOptionalSource: { tag: "a"; value: 1 } | { tag?: "b"; value: 2 }; + declare const matchingOptionalSource: { tag: "a"; value: 1 } | { tag?: "a"; value: 2 } | { tag: "b"; value: 3 }; + declare const requiredMismatchSource: { tag: "a"; value: 1 } | { tag: "b"; value: 2 }; + declare const partiallyMatchingSource: { tag: "a" | "b"; value: 1 } | { tag: "b"; value: 2 }; + declare const undefinedRequiredSource: { tag: "a"; value: 1 } | { tag: undefined; value: 2 }; + declare const explicitUndefinedSource: { tag: "a"; value: 1 } | { tag: "b" | undefined; value: 2 }; + declare const optionalNeverSource: { tag: "a"; value: 1 } | { tag?: never; value: 2 }; + + declare const indexedSource: + | { tag: "a"; value: "a" } + | { tag?: "a"; value: "a" } + | { [key: string]: "b"; value: "b" }; + declare const requiredPropertySource: + | { tag: "a"; value: "a" } + | { [key: string]: "b"; tag: "b"; value: "b" }; + declare const optionalPropertySource: + | { tag: "a"; value: "a" } + | { [key: string]: "a" | "b" | undefined; tag?: "a"; value: "b" }; + + declare function inferOptionalSource(value: { tag?: "a"; value: T }): T; + const validOptional = inferOptionalSource(validOptionalSource); + const mixedOptional = inferOptionalSource(mixedOptionalSource); + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ tag: "a"; value: 1; } | { tag?: "b" | undefined; value: 2; }' is not assignable to parameter of type '{ tag?: "a" | undefined; value: 1 | 2; }'. +!!! error TS2345: Type '{ tag?: "b" | undefined; value: 2; }' is not assignable to type '{ tag?: "a" | undefined; value: 1 | 2; }'. +!!! error TS2345: Types of property 'tag' are incompatible. +!!! error TS2345: Type '"b" | undefined' is not assignable to type '"a" | undefined'. +!!! error TS2345: Type '"b"' is not assignable to type '"a"'. + const matchingOptional = inferOptionalSource(matchingOptionalSource); + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ tag: "a"; value: 1; } | { tag?: "a" | undefined; value: 2; } | { tag: "b"; value: 3; }' is not assignable to parameter of type '{ tag?: "a" | undefined; value: 1 | 2; }'. +!!! error TS2345: Type '{ tag: "b"; value: 3; }' is not assignable to type '{ tag?: "a" | undefined; value: 1 | 2; }'. +!!! error TS2345: Types of property 'tag' are incompatible. +!!! error TS2345: Type '"b"' is not assignable to type '"a"'. + const requiredMismatch = inferOptionalSource(requiredMismatchSource); + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ tag: "a"; value: 1; } | { tag: "b"; value: 2; }' is not assignable to parameter of type '{ tag?: "a" | undefined; value: 1; }'. +!!! error TS2345: Type '{ tag: "b"; value: 2; }' is not assignable to type '{ tag?: "a" | undefined; value: 1; }'. +!!! error TS2345: Types of property 'tag' are incompatible. +!!! error TS2345: Type '"b"' is not assignable to type '"a"'. + const requiredUndefined = inferOptionalSource(undefinedRequiredSource); + const explicitUndefined = inferOptionalSource(explicitUndefinedSource); + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ tag: "a"; value: 1; } | { tag: "b" | undefined; value: 2; }' is not assignable to parameter of type '{ tag?: "a" | undefined; value: 1 | 2; }'. +!!! error TS2345: Type '{ tag: "b" | undefined; value: 2; }' is not assignable to type '{ tag?: "a" | undefined; value: 1 | 2; }'. +!!! error TS2345: Types of property 'tag' are incompatible. +!!! error TS2345: Type '"b" | undefined' is not assignable to type '"a" | undefined'. +!!! error TS2345: Type '"b"' is not assignable to type '"a"'. + const optionalNever = inferOptionalSource(optionalNeverSource); + const indexedOptional = inferOptionalSource(indexedSource); // error + const declaredOptional = inferOptionalSource(optionalPropertySource); // error + const declaredRequired = inferOptionalSource(requiredPropertySource); // error + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ tag: "a"; value: "a"; } | { [key: string]: "b"; tag: "b"; value: "b"; }' is not assignable to parameter of type '{ tag?: "a" | undefined; value: "a"; }'. +!!! error TS2345: Type '{ [key: string]: "b"; tag: "b"; value: "b"; }' is not assignable to type '{ tag?: "a" | undefined; value: "a"; }'. +!!! error TS2345: Types of property 'tag' are incompatible. +!!! error TS2345: Type '"b"' is not assignable to type '"a"'. + + declare function inferRequiredSource(value: { tag: "a"; value: T }): T; + const partiallyMatching = inferRequiredSource(partiallyMatchingSource); + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ tag: "a" | "b"; value: 1; } | { tag: "b"; value: 2; }' is not assignable to parameter of type '{ tag: "a"; value: 1; }'. +!!! error TS2345: Type '{ tag: "a" | "b"; value: 1; }' is not assignable to type '{ tag: "a"; value: 1; }'. +!!! error TS2345: Types of property 'tag' are incompatible. +!!! error TS2345: Type '"a" | "b"' is not assignable to type '"a"'. +!!! error TS2345: Type '"b"' is not assignable to type '"a"'. + const indexedRequired = inferRequiredSource(indexedSource); // error + ~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ tag: "a"; value: "a"; } | { tag?: "a" | undefined; value: "a"; } | { [key: string]: "b"; value: "b"; }' is not assignable to parameter of type '{ tag: "a"; value: "a"; }'. +!!! error TS2345: Type '{ tag?: "a" | undefined; value: "a"; }' is not assignable to type '{ tag: "a"; value: "a"; }'. +!!! error TS2345: Types of property 'tag' are incompatible. +!!! error TS2345: Type '"a" | undefined' is not assignable to type '"a"'. +!!! error TS2345: Type 'undefined' is not assignable to type '"a"'. + + declare function makeOptional(): { tag?: "a"; value: T }; + export function optionalContext(): { tag: "a"; value: 1 } | { tag?: "b"; value: 2 } { + return makeOptional(); + ~~~~~~ +!!! error TS2322: Type '{ tag?: "a" | undefined; value: 1 | 2; }' is not assignable to type '{ tag: "a"; value: 1; } | { tag?: "b" | undefined; value: 2; }'. +!!! error TS2322: Type '{ tag?: "a" | undefined; value: 1 | 2; }' is not assignable to type '{ tag?: "b" | undefined; value: 2; }'. +!!! error TS2322: Types of property 'tag' are incompatible. +!!! error TS2322: Type '"a" | undefined' is not assignable to type '"b" | undefined'. +!!! error TS2322: Type '"a"' is not assignable to type '"b"'. + } + + declare function inferOptionalTargets(value: { tag: "a"; value: A } | { tag?: "b"; value: B }): [A, B]; + declare const optionalInput: { tag?: "a"; value: 42 }; + declare const optionalNeverInput: { tag?: never; value: 42 }; + const optionalTargetInference = inferOptionalTargets(optionalInput); + const optionalNeverTargetInference = inferOptionalTargets(optionalNeverInput); + + // Return type inference runs with the contextual type as the source and the declared + // return type as the target, so assignability has to hold the other way around. + declare function makeTagged(value: T): { kind: "a"; value: T }; + declare function makeOptionalTagged(value: T): { kind?: "a"; value: T }; + declare function makeUnionTagged(value: T): { kind: "a" | undefined; value: T }; + + export function broadContext(): { kind: string; value: string[] } | { kind: "a"; value: number } { + return makeTagged([]); + } + export function partialTagContext(): { kind: "a" | "b"; value: string[] } | { kind: "a"; value: number } { + return makeTagged([]); + } + export function unionTagContext(): { kind?: "a"; value: string[] } | { kind: "a"; value: number } { + return makeUnionTagged([]); + } + export function indexedContext(): + | { [key: string]: string | string[]; value: string[] } + | { kind: "a"; value: number } + | { kind: "b"; value: boolean } { + return makeOptionalTagged([]); + } + + declare function makeEither(a: A, b: B): { kind: "a"; value: A } | { kind: "b"; value: B }; + export function eitherContext(): { kind: "a"; value: string[] } | { kind: "b"; value: number[] } { + return makeEither([], []); + } + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=false).symbols b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=false).symbols new file mode 100644 index 0000000000000..fcf45c198452f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=false).symbols @@ -0,0 +1,334 @@ +//// [tests/cases/compiler/inferenceDiscriminantOverlap.ts] //// + +=== inferenceDiscriminantOverlap.ts === +declare const validOptionalSource: { tag: "a"; value: 1 } | { tag?: "a"; value: 2 }; +>validOptionalSource : Symbol(validOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 0, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 0, 36)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 0, 46)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 0, 61)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 0, 72)) + +declare const mixedOptionalSource: { tag: "a"; value: 1 } | { tag?: "b"; value: 2 }; +>mixedOptionalSource : Symbol(mixedOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 1, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 1, 36)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 1, 46)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 1, 61)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 1, 72)) + +declare const matchingOptionalSource: { tag: "a"; value: 1 } | { tag?: "a"; value: 2 } | { tag: "b"; value: 3 }; +>matchingOptionalSource : Symbol(matchingOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 2, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 2, 39)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 2, 49)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 2, 64)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 2, 75)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 2, 90)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 2, 100)) + +declare const requiredMismatchSource: { tag: "a"; value: 1 } | { tag: "b"; value: 2 }; +>requiredMismatchSource : Symbol(requiredMismatchSource, Decl(inferenceDiscriminantOverlap.ts, 3, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 3, 39)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 3, 49)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 3, 64)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 3, 74)) + +declare const partiallyMatchingSource: { tag: "a" | "b"; value: 1 } | { tag: "b"; value: 2 }; +>partiallyMatchingSource : Symbol(partiallyMatchingSource, Decl(inferenceDiscriminantOverlap.ts, 4, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 4, 40)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 4, 56)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 4, 71)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 4, 81)) + +declare const undefinedRequiredSource: { tag: "a"; value: 1 } | { tag: undefined; value: 2 }; +>undefinedRequiredSource : Symbol(undefinedRequiredSource, Decl(inferenceDiscriminantOverlap.ts, 5, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 5, 40)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 5, 50)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 5, 65)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 5, 81)) + +declare const explicitUndefinedSource: { tag: "a"; value: 1 } | { tag: "b" | undefined; value: 2 }; +>explicitUndefinedSource : Symbol(explicitUndefinedSource, Decl(inferenceDiscriminantOverlap.ts, 6, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 6, 40)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 6, 50)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 6, 65)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 6, 87)) + +declare const optionalNeverSource: { tag: "a"; value: 1 } | { tag?: never; value: 2 }; +>optionalNeverSource : Symbol(optionalNeverSource, Decl(inferenceDiscriminantOverlap.ts, 7, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 7, 36)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 7, 46)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 7, 61)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 7, 74)) + +declare const indexedSource: +>indexedSource : Symbol(indexedSource, Decl(inferenceDiscriminantOverlap.ts, 9, 13)) + + | { tag: "a"; value: "a" } +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 10, 7)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 10, 17)) + + | { tag?: "a"; value: "a" } +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 11, 7)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 11, 18)) + + | { [key: string]: "b"; value: "b" }; +>key : Symbol(key, Decl(inferenceDiscriminantOverlap.ts, 12, 9)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 12, 27)) + +declare const requiredPropertySource: +>requiredPropertySource : Symbol(requiredPropertySource, Decl(inferenceDiscriminantOverlap.ts, 13, 13)) + + | { tag: "a"; value: "a" } +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 14, 7)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 14, 17)) + + | { [key: string]: "b"; tag: "b"; value: "b" }; +>key : Symbol(key, Decl(inferenceDiscriminantOverlap.ts, 15, 9)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 15, 27)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 15, 37)) + +declare const optionalPropertySource: +>optionalPropertySource : Symbol(optionalPropertySource, Decl(inferenceDiscriminantOverlap.ts, 16, 13)) + + | { tag: "a"; value: "a" } +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 17, 7)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 17, 17)) + + | { [key: string]: "a" | "b" | undefined; tag?: "a"; value: "b" }; +>key : Symbol(key, Decl(inferenceDiscriminantOverlap.ts, 18, 9)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 18, 45)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 18, 56)) + +declare function inferOptionalSource(value: { tag?: "a"; value: T }): T; +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 20, 37)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 20, 40)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 20, 48)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 20, 59)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 20, 37)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 20, 37)) + +const validOptional = inferOptionalSource(validOptionalSource); +>validOptional : Symbol(validOptional, Decl(inferenceDiscriminantOverlap.ts, 21, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>validOptionalSource : Symbol(validOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 0, 13)) + +const mixedOptional = inferOptionalSource(mixedOptionalSource); +>mixedOptional : Symbol(mixedOptional, Decl(inferenceDiscriminantOverlap.ts, 22, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>mixedOptionalSource : Symbol(mixedOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 1, 13)) + +const matchingOptional = inferOptionalSource(matchingOptionalSource); +>matchingOptional : Symbol(matchingOptional, Decl(inferenceDiscriminantOverlap.ts, 23, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>matchingOptionalSource : Symbol(matchingOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 2, 13)) + +const requiredMismatch = inferOptionalSource(requiredMismatchSource); +>requiredMismatch : Symbol(requiredMismatch, Decl(inferenceDiscriminantOverlap.ts, 24, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>requiredMismatchSource : Symbol(requiredMismatchSource, Decl(inferenceDiscriminantOverlap.ts, 3, 13)) + +const requiredUndefined = inferOptionalSource(undefinedRequiredSource); +>requiredUndefined : Symbol(requiredUndefined, Decl(inferenceDiscriminantOverlap.ts, 25, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>undefinedRequiredSource : Symbol(undefinedRequiredSource, Decl(inferenceDiscriminantOverlap.ts, 5, 13)) + +const explicitUndefined = inferOptionalSource(explicitUndefinedSource); +>explicitUndefined : Symbol(explicitUndefined, Decl(inferenceDiscriminantOverlap.ts, 26, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>explicitUndefinedSource : Symbol(explicitUndefinedSource, Decl(inferenceDiscriminantOverlap.ts, 6, 13)) + +const optionalNever = inferOptionalSource(optionalNeverSource); +>optionalNever : Symbol(optionalNever, Decl(inferenceDiscriminantOverlap.ts, 27, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>optionalNeverSource : Symbol(optionalNeverSource, Decl(inferenceDiscriminantOverlap.ts, 7, 13)) + +const indexedOptional = inferOptionalSource(indexedSource); // error +>indexedOptional : Symbol(indexedOptional, Decl(inferenceDiscriminantOverlap.ts, 28, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>indexedSource : Symbol(indexedSource, Decl(inferenceDiscriminantOverlap.ts, 9, 13)) + +const declaredOptional = inferOptionalSource(optionalPropertySource); // error +>declaredOptional : Symbol(declaredOptional, Decl(inferenceDiscriminantOverlap.ts, 29, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>optionalPropertySource : Symbol(optionalPropertySource, Decl(inferenceDiscriminantOverlap.ts, 16, 13)) + +const declaredRequired = inferOptionalSource(requiredPropertySource); // error +>declaredRequired : Symbol(declaredRequired, Decl(inferenceDiscriminantOverlap.ts, 30, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>requiredPropertySource : Symbol(requiredPropertySource, Decl(inferenceDiscriminantOverlap.ts, 13, 13)) + +declare function inferRequiredSource(value: { tag: "a"; value: T }): T; +>inferRequiredSource : Symbol(inferRequiredSource, Decl(inferenceDiscriminantOverlap.ts, 30, 69)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 32, 37)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 32, 40)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 32, 48)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 32, 58)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 32, 37)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 32, 37)) + +const partiallyMatching = inferRequiredSource(partiallyMatchingSource); +>partiallyMatching : Symbol(partiallyMatching, Decl(inferenceDiscriminantOverlap.ts, 33, 5)) +>inferRequiredSource : Symbol(inferRequiredSource, Decl(inferenceDiscriminantOverlap.ts, 30, 69)) +>partiallyMatchingSource : Symbol(partiallyMatchingSource, Decl(inferenceDiscriminantOverlap.ts, 4, 13)) + +const indexedRequired = inferRequiredSource(indexedSource); // error +>indexedRequired : Symbol(indexedRequired, Decl(inferenceDiscriminantOverlap.ts, 34, 5)) +>inferRequiredSource : Symbol(inferRequiredSource, Decl(inferenceDiscriminantOverlap.ts, 30, 69)) +>indexedSource : Symbol(indexedSource, Decl(inferenceDiscriminantOverlap.ts, 9, 13)) + +declare function makeOptional(): { tag?: "a"; value: T }; +>makeOptional : Symbol(makeOptional, Decl(inferenceDiscriminantOverlap.ts, 34, 59)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 36, 30)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 36, 43)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 36, 54)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 36, 30)) + +export function optionalContext(): { tag: "a"; value: 1 } | { tag?: "b"; value: 2 } { +>optionalContext : Symbol(optionalContext, Decl(inferenceDiscriminantOverlap.ts, 36, 66)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 37, 36)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 37, 46)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 37, 61)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 37, 72)) + + return makeOptional(); +>makeOptional : Symbol(makeOptional, Decl(inferenceDiscriminantOverlap.ts, 34, 59)) +} + +declare function inferOptionalTargets(value: { tag: "a"; value: A } | { tag?: "b"; value: B }): [A, B]; +>inferOptionalTargets : Symbol(inferOptionalTargets, Decl(inferenceDiscriminantOverlap.ts, 39, 1)) +>A : Symbol(A, Decl(inferenceDiscriminantOverlap.ts, 41, 38)) +>B : Symbol(B, Decl(inferenceDiscriminantOverlap.ts, 41, 40)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 41, 44)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 41, 52)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 41, 62)) +>A : Symbol(A, Decl(inferenceDiscriminantOverlap.ts, 41, 38)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 41, 77)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 41, 88)) +>B : Symbol(B, Decl(inferenceDiscriminantOverlap.ts, 41, 40)) +>A : Symbol(A, Decl(inferenceDiscriminantOverlap.ts, 41, 38)) +>B : Symbol(B, Decl(inferenceDiscriminantOverlap.ts, 41, 40)) + +declare const optionalInput: { tag?: "a"; value: 42 }; +>optionalInput : Symbol(optionalInput, Decl(inferenceDiscriminantOverlap.ts, 42, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 42, 30)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 42, 41)) + +declare const optionalNeverInput: { tag?: never; value: 42 }; +>optionalNeverInput : Symbol(optionalNeverInput, Decl(inferenceDiscriminantOverlap.ts, 43, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 43, 35)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 43, 48)) + +const optionalTargetInference = inferOptionalTargets(optionalInput); +>optionalTargetInference : Symbol(optionalTargetInference, Decl(inferenceDiscriminantOverlap.ts, 44, 5)) +>inferOptionalTargets : Symbol(inferOptionalTargets, Decl(inferenceDiscriminantOverlap.ts, 39, 1)) +>optionalInput : Symbol(optionalInput, Decl(inferenceDiscriminantOverlap.ts, 42, 13)) + +const optionalNeverTargetInference = inferOptionalTargets(optionalNeverInput); +>optionalNeverTargetInference : Symbol(optionalNeverTargetInference, Decl(inferenceDiscriminantOverlap.ts, 45, 5)) +>inferOptionalTargets : Symbol(inferOptionalTargets, Decl(inferenceDiscriminantOverlap.ts, 39, 1)) +>optionalNeverInput : Symbol(optionalNeverInput, Decl(inferenceDiscriminantOverlap.ts, 43, 13)) + +// Return type inference runs with the contextual type as the source and the declared +// return type as the target, so assignability has to hold the other way around. +declare function makeTagged(value: T): { kind: "a"; value: T }; +>makeTagged : Symbol(makeTagged, Decl(inferenceDiscriminantOverlap.ts, 45, 78)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 49, 28)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 49, 37)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 49, 28)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 49, 49)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 49, 60)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 49, 28)) + +declare function makeOptionalTagged(value: T): { kind?: "a"; value: T }; +>makeOptionalTagged : Symbol(makeOptionalTagged, Decl(inferenceDiscriminantOverlap.ts, 49, 72)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 50, 36)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 50, 45)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 50, 36)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 50, 57)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 50, 69)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 50, 36)) + +declare function makeUnionTagged(value: T): { kind: "a" | undefined; value: T }; +>makeUnionTagged : Symbol(makeUnionTagged, Decl(inferenceDiscriminantOverlap.ts, 50, 81)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 51, 33)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 51, 42)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 51, 33)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 51, 54)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 51, 77)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 51, 33)) + +export function broadContext(): { kind: string; value: string[] } | { kind: "a"; value: number } { +>broadContext : Symbol(broadContext, Decl(inferenceDiscriminantOverlap.ts, 51, 89)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 53, 33)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 53, 47)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 53, 69)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 53, 80)) + + return makeTagged([]); +>makeTagged : Symbol(makeTagged, Decl(inferenceDiscriminantOverlap.ts, 45, 78)) +} +export function partialTagContext(): { kind: "a" | "b"; value: string[] } | { kind: "a"; value: number } { +>partialTagContext : Symbol(partialTagContext, Decl(inferenceDiscriminantOverlap.ts, 55, 1)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 56, 38)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 56, 55)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 56, 77)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 56, 88)) + + return makeTagged([]); +>makeTagged : Symbol(makeTagged, Decl(inferenceDiscriminantOverlap.ts, 45, 78)) +} +export function unionTagContext(): { kind?: "a"; value: string[] } | { kind: "a"; value: number } { +>unionTagContext : Symbol(unionTagContext, Decl(inferenceDiscriminantOverlap.ts, 58, 1)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 59, 36)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 59, 48)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 59, 70)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 59, 81)) + + return makeUnionTagged([]); +>makeUnionTagged : Symbol(makeUnionTagged, Decl(inferenceDiscriminantOverlap.ts, 50, 81)) +} +export function indexedContext(): +>indexedContext : Symbol(indexedContext, Decl(inferenceDiscriminantOverlap.ts, 61, 1)) + + | { [key: string]: string | string[]; value: string[] } +>key : Symbol(key, Decl(inferenceDiscriminantOverlap.ts, 63, 9)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 63, 41)) + + | { kind: "a"; value: number } +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 64, 7)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 64, 18)) + + | { kind: "b"; value: boolean } { +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 65, 7)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 65, 18)) + + return makeOptionalTagged([]); +>makeOptionalTagged : Symbol(makeOptionalTagged, Decl(inferenceDiscriminantOverlap.ts, 49, 72)) +} + +declare function makeEither(a: A, b: B): { kind: "a"; value: A } | { kind: "b"; value: B }; +>makeEither : Symbol(makeEither, Decl(inferenceDiscriminantOverlap.ts, 67, 1)) +>A : Symbol(A, Decl(inferenceDiscriminantOverlap.ts, 69, 28)) +>B : Symbol(B, Decl(inferenceDiscriminantOverlap.ts, 69, 36)) +>a : Symbol(a, Decl(inferenceDiscriminantOverlap.ts, 69, 46)) +>A : Symbol(A, Decl(inferenceDiscriminantOverlap.ts, 69, 28)) +>b : Symbol(b, Decl(inferenceDiscriminantOverlap.ts, 69, 51)) +>B : Symbol(B, Decl(inferenceDiscriminantOverlap.ts, 69, 36)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 69, 60)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 69, 71)) +>A : Symbol(A, Decl(inferenceDiscriminantOverlap.ts, 69, 28)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 69, 86)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 69, 97)) +>B : Symbol(B, Decl(inferenceDiscriminantOverlap.ts, 69, 36)) + +export function eitherContext(): { kind: "a"; value: string[] } | { kind: "b"; value: number[] } { +>eitherContext : Symbol(eitherContext, Decl(inferenceDiscriminantOverlap.ts, 69, 109)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 70, 34)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 70, 45)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 70, 67)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 70, 78)) + + return makeEither([], []); +>makeEither : Symbol(makeEither, Decl(inferenceDiscriminantOverlap.ts, 67, 1)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=false).types b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=false).types new file mode 100644 index 0000000000000..23ed13fce9665 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=false).types @@ -0,0 +1,331 @@ +//// [tests/cases/compiler/inferenceDiscriminantOverlap.ts] //// + +=== inferenceDiscriminantOverlap.ts === +declare const validOptionalSource: { tag: "a"; value: 1 } | { tag?: "a"; value: 2 }; +>validOptionalSource : { tag: "a"; value: 1; } | { tag?: "a"; value: 2; } +>tag : "a" +>value : 1 +>tag : "a" | undefined +>value : 2 + +declare const mixedOptionalSource: { tag: "a"; value: 1 } | { tag?: "b"; value: 2 }; +>mixedOptionalSource : { tag: "a"; value: 1; } | { tag?: "b"; value: 2; } +>tag : "a" +>value : 1 +>tag : "b" | undefined +>value : 2 + +declare const matchingOptionalSource: { tag: "a"; value: 1 } | { tag?: "a"; value: 2 } | { tag: "b"; value: 3 }; +>matchingOptionalSource : { tag: "a"; value: 1; } | { tag?: "a"; value: 2; } | { tag: "b"; value: 3; } +>tag : "a" +>value : 1 +>tag : "a" | undefined +>value : 2 +>tag : "b" +>value : 3 + +declare const requiredMismatchSource: { tag: "a"; value: 1 } | { tag: "b"; value: 2 }; +>requiredMismatchSource : { tag: "a"; value: 1; } | { tag: "b"; value: 2; } +>tag : "a" +>value : 1 +>tag : "b" +>value : 2 + +declare const partiallyMatchingSource: { tag: "a" | "b"; value: 1 } | { tag: "b"; value: 2 }; +>partiallyMatchingSource : { tag: "a" | "b"; value: 1; } | { tag: "b"; value: 2; } +>tag : "a" | "b" +>value : 1 +>tag : "b" +>value : 2 + +declare const undefinedRequiredSource: { tag: "a"; value: 1 } | { tag: undefined; value: 2 }; +>undefinedRequiredSource : { tag: "a"; value: 1; } | { tag: undefined; value: 2; } +>tag : "a" +>value : 1 +>tag : undefined +>value : 2 + +declare const explicitUndefinedSource: { tag: "a"; value: 1 } | { tag: "b" | undefined; value: 2 }; +>explicitUndefinedSource : { tag: "a"; value: 1; } | { tag: "b" | undefined; value: 2; } +>tag : "a" +>value : 1 +>tag : "b" | undefined +>value : 2 + +declare const optionalNeverSource: { tag: "a"; value: 1 } | { tag?: never; value: 2 }; +>optionalNeverSource : { tag: "a"; value: 1; } | { tag?: never; value: 2; } +>tag : "a" +>value : 1 +>tag : undefined +>value : 2 + +declare const indexedSource: +>indexedSource : { tag: "a"; value: "a"; } | { tag?: "a"; value: "a"; } | { [key: string]: "b"; value: "b"; } + + | { tag: "a"; value: "a" } +>tag : "a" +>value : "a" + + | { tag?: "a"; value: "a" } +>tag : "a" | undefined +>value : "a" + + | { [key: string]: "b"; value: "b" }; +>key : string +>value : "b" + +declare const requiredPropertySource: +>requiredPropertySource : { tag: "a"; value: "a"; } | { [key: string]: "b"; tag: "b"; value: "b"; } + + | { tag: "a"; value: "a" } +>tag : "a" +>value : "a" + + | { [key: string]: "b"; tag: "b"; value: "b" }; +>key : string +>tag : "b" +>value : "b" + +declare const optionalPropertySource: +>optionalPropertySource : { tag: "a"; value: "a"; } | { [key: string]: "a" | "b" | undefined; tag?: "a"; value: "b"; } + + | { tag: "a"; value: "a" } +>tag : "a" +>value : "a" + + | { [key: string]: "a" | "b" | undefined; tag?: "a"; value: "b" }; +>key : string +>tag : "a" | undefined +>value : "b" + +declare function inferOptionalSource(value: { tag?: "a"; value: T }): T; +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>value : { tag?: "a"; value: T; } +>tag : "a" | undefined +>value : T + +const validOptional = inferOptionalSource(validOptionalSource); +>validOptional : 1 | 2 +>inferOptionalSource(validOptionalSource) : 1 | 2 +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>validOptionalSource : { tag: "a"; value: 1; } | { tag?: "a"; value: 2; } + +const mixedOptional = inferOptionalSource(mixedOptionalSource); +>mixedOptional : 1 | 2 +>inferOptionalSource(mixedOptionalSource) : 1 | 2 +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>mixedOptionalSource : { tag: "a"; value: 1; } | { tag?: "b"; value: 2; } + +const matchingOptional = inferOptionalSource(matchingOptionalSource); +>matchingOptional : 1 | 2 +>inferOptionalSource(matchingOptionalSource) : 1 | 2 +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>matchingOptionalSource : { tag: "a"; value: 1; } | { tag?: "a"; value: 2; } | { tag: "b"; value: 3; } + +const requiredMismatch = inferOptionalSource(requiredMismatchSource); +>requiredMismatch : 1 +>inferOptionalSource(requiredMismatchSource) : 1 +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>requiredMismatchSource : { tag: "a"; value: 1; } | { tag: "b"; value: 2; } + +const requiredUndefined = inferOptionalSource(undefinedRequiredSource); +>requiredUndefined : 1 | 2 +>inferOptionalSource(undefinedRequiredSource) : 1 | 2 +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>undefinedRequiredSource : { tag: "a"; value: 1; } | { tag: undefined; value: 2; } + +const explicitUndefined = inferOptionalSource(explicitUndefinedSource); +>explicitUndefined : 1 | 2 +>inferOptionalSource(explicitUndefinedSource) : 1 | 2 +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>explicitUndefinedSource : { tag: "a"; value: 1; } | { tag: "b" | undefined; value: 2; } + +const optionalNever = inferOptionalSource(optionalNeverSource); +>optionalNever : 1 | 2 +>inferOptionalSource(optionalNeverSource) : 1 | 2 +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>optionalNeverSource : { tag: "a"; value: 1; } | { tag?: never; value: 2; } + +const indexedOptional = inferOptionalSource(indexedSource); // error +>indexedOptional : "a" | "b" +>inferOptionalSource(indexedSource) : "a" | "b" +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>indexedSource : { tag: "a"; value: "a"; } | { tag?: "a"; value: "a"; } | { [key: string]: "b"; value: "b"; } + +const declaredOptional = inferOptionalSource(optionalPropertySource); // error +>declaredOptional : "a" | "b" +>inferOptionalSource(optionalPropertySource) : "a" | "b" +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>optionalPropertySource : { tag: "a"; value: "a"; } | { [key: string]: "a" | "b" | undefined; tag?: "a"; value: "b"; } + +const declaredRequired = inferOptionalSource(requiredPropertySource); // error +>declaredRequired : "a" +>inferOptionalSource(requiredPropertySource) : "a" +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>requiredPropertySource : { tag: "a"; value: "a"; } | { [key: string]: "b"; tag: "b"; value: "b"; } + +declare function inferRequiredSource(value: { tag: "a"; value: T }): T; +>inferRequiredSource : (value: { tag: "a"; value: T; }) => T +>value : { tag: "a"; value: T; } +>tag : "a" +>value : T + +const partiallyMatching = inferRequiredSource(partiallyMatchingSource); +>partiallyMatching : 1 +>inferRequiredSource(partiallyMatchingSource) : 1 +>inferRequiredSource : (value: { tag: "a"; value: T; }) => T +>partiallyMatchingSource : { tag: "a" | "b"; value: 1; } | { tag: "b"; value: 2; } + +const indexedRequired = inferRequiredSource(indexedSource); // error +>indexedRequired : "a" +>inferRequiredSource(indexedSource) : "a" +>inferRequiredSource : (value: { tag: "a"; value: T; }) => T +>indexedSource : { tag: "a"; value: "a"; } | { tag?: "a"; value: "a"; } | { [key: string]: "b"; value: "b"; } + +declare function makeOptional(): { tag?: "a"; value: T }; +>makeOptional : () => { tag?: "a"; value: T; } +>tag : "a" | undefined +>value : T + +export function optionalContext(): { tag: "a"; value: 1 } | { tag?: "b"; value: 2 } { +>optionalContext : () => { tag: "a"; value: 1; } | { tag?: "b"; value: 2; } +>tag : "a" +>value : 1 +>tag : "b" | undefined +>value : 2 + + return makeOptional(); +>makeOptional() : { tag?: "a"; value: 1 | 2; } +>makeOptional : () => { tag?: "a"; value: T; } +} + +declare function inferOptionalTargets(value: { tag: "a"; value: A } | { tag?: "b"; value: B }): [A, B]; +>inferOptionalTargets : (value: { tag: "a"; value: A; } | { tag?: "b"; value: B; }) => [A, B] +>value : { tag: "a"; value: A; } | { tag?: "b"; value: B; } +>tag : "a" +>value : A +>tag : "b" | undefined +>value : B + +declare const optionalInput: { tag?: "a"; value: 42 }; +>optionalInput : { tag?: "a"; value: 42; } +>tag : "a" | undefined +>value : 42 + +declare const optionalNeverInput: { tag?: never; value: 42 }; +>optionalNeverInput : { tag?: never; value: 42; } +>tag : undefined +>value : 42 + +const optionalTargetInference = inferOptionalTargets(optionalInput); +>optionalTargetInference : [42, 42] +>inferOptionalTargets(optionalInput) : [42, 42] +>inferOptionalTargets : (value: { tag: "a"; value: A; } | { tag?: "b"; value: B; }) => [A, B] +>optionalInput : { tag?: "a"; value: 42; } + +const optionalNeverTargetInference = inferOptionalTargets(optionalNeverInput); +>optionalNeverTargetInference : [unknown, 42] +>inferOptionalTargets(optionalNeverInput) : [unknown, 42] +>inferOptionalTargets : (value: { tag: "a"; value: A; } | { tag?: "b"; value: B; }) => [A, B] +>optionalNeverInput : { tag?: never; value: 42; } + +// Return type inference runs with the contextual type as the source and the declared +// return type as the target, so assignability has to hold the other way around. +declare function makeTagged(value: T): { kind: "a"; value: T }; +>makeTagged : (value: T) => { kind: "a"; value: T; } +>value : T +>kind : "a" +>value : T + +declare function makeOptionalTagged(value: T): { kind?: "a"; value: T }; +>makeOptionalTagged : (value: T) => { kind?: "a"; value: T; } +>value : T +>kind : "a" | undefined +>value : T + +declare function makeUnionTagged(value: T): { kind: "a" | undefined; value: T }; +>makeUnionTagged : (value: T) => { kind: "a" | undefined; value: T; } +>value : T +>kind : "a" | undefined +>value : T + +export function broadContext(): { kind: string; value: string[] } | { kind: "a"; value: number } { +>broadContext : () => { kind: string; value: string[]; } | { kind: "a"; value: number; } +>kind : string +>value : string[] +>kind : "a" +>value : number + + return makeTagged([]); +>makeTagged([]) : { kind: "a"; value: []; } +>makeTagged : (value: T) => { kind: "a"; value: T; } +>[] : [] +} +export function partialTagContext(): { kind: "a" | "b"; value: string[] } | { kind: "a"; value: number } { +>partialTagContext : () => { kind: "a" | "b"; value: string[]; } | { kind: "a"; value: number; } +>kind : "a" | "b" +>value : string[] +>kind : "a" +>value : number + + return makeTagged([]); +>makeTagged([]) : { kind: "a"; value: []; } +>makeTagged : (value: T) => { kind: "a"; value: T; } +>[] : [] +} +export function unionTagContext(): { kind?: "a"; value: string[] } | { kind: "a"; value: number } { +>unionTagContext : () => { kind?: "a"; value: string[]; } | { kind: "a"; value: number; } +>kind : "a" | undefined +>value : string[] +>kind : "a" +>value : number + + return makeUnionTagged([]); +>makeUnionTagged([]) : { kind: "a" | undefined; value: []; } +>makeUnionTagged : (value: T) => { kind: "a" | undefined; value: T; } +>[] : [] +} +export function indexedContext(): +>indexedContext : () => { [key: string]: string | string[]; value: string[]; } | { kind: "a"; value: number; } | { kind: "b"; value: boolean; } + + | { [key: string]: string | string[]; value: string[] } +>key : string +>value : string[] + + | { kind: "a"; value: number } +>kind : "a" +>value : number + + | { kind: "b"; value: boolean } { +>kind : "b" +>value : boolean + + return makeOptionalTagged([]); +>makeOptionalTagged([]) : { kind?: "a"; value: []; } +>makeOptionalTagged : (value: T) => { kind?: "a"; value: T; } +>[] : [] +} + +declare function makeEither(a: A, b: B): { kind: "a"; value: A } | { kind: "b"; value: B }; +>makeEither : (a: A, b: B) => { kind: "a"; value: A; } | { kind: "b"; value: B; } +>a : A +>b : B +>kind : "a" +>value : A +>kind : "b" +>value : B + +export function eitherContext(): { kind: "a"; value: string[] } | { kind: "b"; value: number[] } { +>eitherContext : () => { kind: "a"; value: string[]; } | { kind: "b"; value: number[]; } +>kind : "a" +>value : string[] +>kind : "b" +>value : number[] + + return makeEither([], []); +>makeEither([], []) : { kind: "a"; value: []; } | { kind: "b"; value: []; } +>makeEither : (a: A, b: B) => { kind: "a"; value: A; } | { kind: "b"; value: B; } +>[] : [] +>[] : [] +} + diff --git a/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=true).errors.txt b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=true).errors.txt new file mode 100644 index 0000000000000..e36038126dca7 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=true).errors.txt @@ -0,0 +1,171 @@ +inferenceDiscriminantOverlap.ts(23,43): error TS2379: Argument of type '{ tag: "a"; value: 1; } | { tag?: "b"; value: 2; }' is not assignable to parameter of type '{ tag?: "a"; value: 1 | 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Type '{ tag?: "b"; value: 2; }' is not assignable to type '{ tag?: "a"; value: 1 | 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Types of property 'tag' are incompatible. + Type '"b"' is not assignable to type '"a"'. +inferenceDiscriminantOverlap.ts(24,46): error TS2379: Argument of type '{ tag: "a"; value: 1; } | { tag?: "a"; value: 2; } | { tag: "b"; value: 3; }' is not assignable to parameter of type '{ tag?: "a"; value: 1 | 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Type '{ tag: "b"; value: 3; }' is not assignable to type '{ tag?: "a"; value: 1 | 2; }'. + Types of property 'tag' are incompatible. + Type '"b"' is not assignable to type '"a"'. +inferenceDiscriminantOverlap.ts(25,46): error TS2345: Argument of type '{ tag: "a"; value: 1; } | { tag: "b"; value: 2; }' is not assignable to parameter of type '{ tag?: "a"; value: 1; }'. + Type '{ tag: "b"; value: 2; }' is not assignable to type '{ tag?: "a"; value: 1; }'. + Types of property 'tag' are incompatible. + Type '"b"' is not assignable to type '"a"'. +inferenceDiscriminantOverlap.ts(26,47): error TS2379: Argument of type '{ tag: "a"; value: 1; } | { tag: undefined; value: 2; }' is not assignable to parameter of type '{ tag?: "a"; value: 1 | 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Type '{ tag: undefined; value: 2; }' is not assignable to type '{ tag?: "a"; value: 1 | 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Types of property 'tag' are incompatible. + Type 'undefined' is not assignable to type '"a"'. +inferenceDiscriminantOverlap.ts(27,47): error TS2379: Argument of type '{ tag: "a"; value: 1; } | { tag: "b" | undefined; value: 2; }' is not assignable to parameter of type '{ tag?: "a"; value: 1 | 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Type '{ tag: "b" | undefined; value: 2; }' is not assignable to type '{ tag?: "a"; value: 1 | 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Types of property 'tag' are incompatible. + Type '"b" | undefined' is not assignable to type '"a"'. + Type 'undefined' is not assignable to type '"a"'. +inferenceDiscriminantOverlap.ts(31,46): error TS2345: Argument of type '{ tag: "a"; value: "a"; } | { [key: string]: "b"; tag: "b"; value: "b"; }' is not assignable to parameter of type '{ tag?: "a"; value: "a"; }'. + Type '{ [key: string]: "b"; tag: "b"; value: "b"; }' is not assignable to type '{ tag?: "a"; value: "a"; }'. + Types of property 'tag' are incompatible. + Type '"b"' is not assignable to type '"a"'. +inferenceDiscriminantOverlap.ts(34,47): error TS2345: Argument of type '{ tag: "a" | "b"; value: 1; } | { tag: "b"; value: 2; }' is not assignable to parameter of type '{ tag: "a"; value: 1; }'. + Type '{ tag: "a" | "b"; value: 1; }' is not assignable to type '{ tag: "a"; value: 1; }'. + Types of property 'tag' are incompatible. + Type '"a" | "b"' is not assignable to type '"a"'. + Type '"b"' is not assignable to type '"a"'. +inferenceDiscriminantOverlap.ts(35,45): error TS2345: Argument of type '{ tag: "a"; value: "a"; } | { tag?: "a"; value: "a"; } | { [key: string]: "b"; value: "b"; }' is not assignable to parameter of type '{ tag: "a"; value: "a"; }'. + Type '{ tag?: "a"; value: "a"; }' is not assignable to type '{ tag: "a"; value: "a"; }'. + Property 'tag' is optional in type '{ tag?: "a"; value: "a"; }' but required in type '{ tag: "a"; value: "a"; }'. +inferenceDiscriminantOverlap.ts(39,5): error TS2375: Type '{ tag?: "a"; value: 1 | 2; }' is not assignable to type '{ tag: "a"; value: 1; } | { tag?: "b"; value: 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Type '{ tag?: "a"; value: 1 | 2; }' is not assignable to type '{ tag?: "b"; value: 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Types of property 'tag' are incompatible. + Type '"a"' is not assignable to type '"b"'. +inferenceDiscriminantOverlap.ts(61,5): error TS2375: Type '{ kind: "a" | undefined; value: []; }' is not assignable to type '{ kind?: "a"; value: string[]; } | { kind: "a"; value: number; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Type '{ kind: "a" | undefined; value: []; }' is not assignable to type '{ kind: "a"; value: number; }'. + Types of property 'kind' are incompatible. + Type '"a" | undefined' is not assignable to type '"a"'. + Type 'undefined' is not assignable to type '"a"'. + + +==== inferenceDiscriminantOverlap.ts (10 errors) ==== + declare const validOptionalSource: { tag: "a"; value: 1 } | { tag?: "a"; value: 2 }; + declare const mixedOptionalSource: { tag: "a"; value: 1 } | { tag?: "b"; value: 2 }; + declare const matchingOptionalSource: { tag: "a"; value: 1 } | { tag?: "a"; value: 2 } | { tag: "b"; value: 3 }; + declare const requiredMismatchSource: { tag: "a"; value: 1 } | { tag: "b"; value: 2 }; + declare const partiallyMatchingSource: { tag: "a" | "b"; value: 1 } | { tag: "b"; value: 2 }; + declare const undefinedRequiredSource: { tag: "a"; value: 1 } | { tag: undefined; value: 2 }; + declare const explicitUndefinedSource: { tag: "a"; value: 1 } | { tag: "b" | undefined; value: 2 }; + declare const optionalNeverSource: { tag: "a"; value: 1 } | { tag?: never; value: 2 }; + + declare const indexedSource: + | { tag: "a"; value: "a" } + | { tag?: "a"; value: "a" } + | { [key: string]: "b"; value: "b" }; + declare const requiredPropertySource: + | { tag: "a"; value: "a" } + | { [key: string]: "b"; tag: "b"; value: "b" }; + declare const optionalPropertySource: + | { tag: "a"; value: "a" } + | { [key: string]: "a" | "b" | undefined; tag?: "a"; value: "b" }; + + declare function inferOptionalSource(value: { tag?: "a"; value: T }): T; + const validOptional = inferOptionalSource(validOptionalSource); + const mixedOptional = inferOptionalSource(mixedOptionalSource); + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2379: Argument of type '{ tag: "a"; value: 1; } | { tag?: "b"; value: 2; }' is not assignable to parameter of type '{ tag?: "a"; value: 1 | 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2379: Type '{ tag?: "b"; value: 2; }' is not assignable to type '{ tag?: "a"; value: 1 | 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2379: Types of property 'tag' are incompatible. +!!! error TS2379: Type '"b"' is not assignable to type '"a"'. + const matchingOptional = inferOptionalSource(matchingOptionalSource); + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2379: Argument of type '{ tag: "a"; value: 1; } | { tag?: "a"; value: 2; } | { tag: "b"; value: 3; }' is not assignable to parameter of type '{ tag?: "a"; value: 1 | 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2379: Type '{ tag: "b"; value: 3; }' is not assignable to type '{ tag?: "a"; value: 1 | 2; }'. +!!! error TS2379: Types of property 'tag' are incompatible. +!!! error TS2379: Type '"b"' is not assignable to type '"a"'. + const requiredMismatch = inferOptionalSource(requiredMismatchSource); + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ tag: "a"; value: 1; } | { tag: "b"; value: 2; }' is not assignable to parameter of type '{ tag?: "a"; value: 1; }'. +!!! error TS2345: Type '{ tag: "b"; value: 2; }' is not assignable to type '{ tag?: "a"; value: 1; }'. +!!! error TS2345: Types of property 'tag' are incompatible. +!!! error TS2345: Type '"b"' is not assignable to type '"a"'. + const requiredUndefined = inferOptionalSource(undefinedRequiredSource); + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2379: Argument of type '{ tag: "a"; value: 1; } | { tag: undefined; value: 2; }' is not assignable to parameter of type '{ tag?: "a"; value: 1 | 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2379: Type '{ tag: undefined; value: 2; }' is not assignable to type '{ tag?: "a"; value: 1 | 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2379: Types of property 'tag' are incompatible. +!!! error TS2379: Type 'undefined' is not assignable to type '"a"'. + const explicitUndefined = inferOptionalSource(explicitUndefinedSource); + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2379: Argument of type '{ tag: "a"; value: 1; } | { tag: "b" | undefined; value: 2; }' is not assignable to parameter of type '{ tag?: "a"; value: 1 | 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2379: Type '{ tag: "b" | undefined; value: 2; }' is not assignable to type '{ tag?: "a"; value: 1 | 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2379: Types of property 'tag' are incompatible. +!!! error TS2379: Type '"b" | undefined' is not assignable to type '"a"'. +!!! error TS2379: Type 'undefined' is not assignable to type '"a"'. + const optionalNever = inferOptionalSource(optionalNeverSource); + const indexedOptional = inferOptionalSource(indexedSource); // error + const declaredOptional = inferOptionalSource(optionalPropertySource); // error + const declaredRequired = inferOptionalSource(requiredPropertySource); // error + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ tag: "a"; value: "a"; } | { [key: string]: "b"; tag: "b"; value: "b"; }' is not assignable to parameter of type '{ tag?: "a"; value: "a"; }'. +!!! error TS2345: Type '{ [key: string]: "b"; tag: "b"; value: "b"; }' is not assignable to type '{ tag?: "a"; value: "a"; }'. +!!! error TS2345: Types of property 'tag' are incompatible. +!!! error TS2345: Type '"b"' is not assignable to type '"a"'. + + declare function inferRequiredSource(value: { tag: "a"; value: T }): T; + const partiallyMatching = inferRequiredSource(partiallyMatchingSource); + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ tag: "a" | "b"; value: 1; } | { tag: "b"; value: 2; }' is not assignable to parameter of type '{ tag: "a"; value: 1; }'. +!!! error TS2345: Type '{ tag: "a" | "b"; value: 1; }' is not assignable to type '{ tag: "a"; value: 1; }'. +!!! error TS2345: Types of property 'tag' are incompatible. +!!! error TS2345: Type '"a" | "b"' is not assignable to type '"a"'. +!!! error TS2345: Type '"b"' is not assignable to type '"a"'. + const indexedRequired = inferRequiredSource(indexedSource); // error + ~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ tag: "a"; value: "a"; } | { tag?: "a"; value: "a"; } | { [key: string]: "b"; value: "b"; }' is not assignable to parameter of type '{ tag: "a"; value: "a"; }'. +!!! error TS2345: Type '{ tag?: "a"; value: "a"; }' is not assignable to type '{ tag: "a"; value: "a"; }'. +!!! error TS2345: Property 'tag' is optional in type '{ tag?: "a"; value: "a"; }' but required in type '{ tag: "a"; value: "a"; }'. + + declare function makeOptional(): { tag?: "a"; value: T }; + export function optionalContext(): { tag: "a"; value: 1 } | { tag?: "b"; value: 2 } { + return makeOptional(); + ~~~~~~ +!!! error TS2375: Type '{ tag?: "a"; value: 1 | 2; }' is not assignable to type '{ tag: "a"; value: 1; } | { tag?: "b"; value: 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2375: Type '{ tag?: "a"; value: 1 | 2; }' is not assignable to type '{ tag?: "b"; value: 2; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2375: Types of property 'tag' are incompatible. +!!! error TS2375: Type '"a"' is not assignable to type '"b"'. + } + + declare function inferOptionalTargets(value: { tag: "a"; value: A } | { tag?: "b"; value: B }): [A, B]; + declare const optionalInput: { tag?: "a"; value: 42 }; + declare const optionalNeverInput: { tag?: never; value: 42 }; + const optionalTargetInference = inferOptionalTargets(optionalInput); + const optionalNeverTargetInference = inferOptionalTargets(optionalNeverInput); + + // Return type inference runs with the contextual type as the source and the declared + // return type as the target, so assignability has to hold the other way around. + declare function makeTagged(value: T): { kind: "a"; value: T }; + declare function makeOptionalTagged(value: T): { kind?: "a"; value: T }; + declare function makeUnionTagged(value: T): { kind: "a" | undefined; value: T }; + + export function broadContext(): { kind: string; value: string[] } | { kind: "a"; value: number } { + return makeTagged([]); + } + export function partialTagContext(): { kind: "a" | "b"; value: string[] } | { kind: "a"; value: number } { + return makeTagged([]); + } + export function unionTagContext(): { kind?: "a"; value: string[] } | { kind: "a"; value: number } { + return makeUnionTagged([]); + ~~~~~~ +!!! error TS2375: Type '{ kind: "a" | undefined; value: []; }' is not assignable to type '{ kind?: "a"; value: string[]; } | { kind: "a"; value: number; }' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2375: Type '{ kind: "a" | undefined; value: []; }' is not assignable to type '{ kind: "a"; value: number; }'. +!!! error TS2375: Types of property 'kind' are incompatible. +!!! error TS2375: Type '"a" | undefined' is not assignable to type '"a"'. +!!! error TS2375: Type 'undefined' is not assignable to type '"a"'. + } + export function indexedContext(): + | { [key: string]: string | string[]; value: string[] } + | { kind: "a"; value: number } + | { kind: "b"; value: boolean } { + return makeOptionalTagged([]); + } + + declare function makeEither(a: A, b: B): { kind: "a"; value: A } | { kind: "b"; value: B }; + export function eitherContext(): { kind: "a"; value: string[] } | { kind: "b"; value: number[] } { + return makeEither([], []); + } + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=true).symbols b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=true).symbols new file mode 100644 index 0000000000000..fcf45c198452f --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=true).symbols @@ -0,0 +1,334 @@ +//// [tests/cases/compiler/inferenceDiscriminantOverlap.ts] //// + +=== inferenceDiscriminantOverlap.ts === +declare const validOptionalSource: { tag: "a"; value: 1 } | { tag?: "a"; value: 2 }; +>validOptionalSource : Symbol(validOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 0, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 0, 36)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 0, 46)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 0, 61)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 0, 72)) + +declare const mixedOptionalSource: { tag: "a"; value: 1 } | { tag?: "b"; value: 2 }; +>mixedOptionalSource : Symbol(mixedOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 1, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 1, 36)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 1, 46)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 1, 61)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 1, 72)) + +declare const matchingOptionalSource: { tag: "a"; value: 1 } | { tag?: "a"; value: 2 } | { tag: "b"; value: 3 }; +>matchingOptionalSource : Symbol(matchingOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 2, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 2, 39)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 2, 49)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 2, 64)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 2, 75)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 2, 90)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 2, 100)) + +declare const requiredMismatchSource: { tag: "a"; value: 1 } | { tag: "b"; value: 2 }; +>requiredMismatchSource : Symbol(requiredMismatchSource, Decl(inferenceDiscriminantOverlap.ts, 3, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 3, 39)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 3, 49)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 3, 64)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 3, 74)) + +declare const partiallyMatchingSource: { tag: "a" | "b"; value: 1 } | { tag: "b"; value: 2 }; +>partiallyMatchingSource : Symbol(partiallyMatchingSource, Decl(inferenceDiscriminantOverlap.ts, 4, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 4, 40)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 4, 56)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 4, 71)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 4, 81)) + +declare const undefinedRequiredSource: { tag: "a"; value: 1 } | { tag: undefined; value: 2 }; +>undefinedRequiredSource : Symbol(undefinedRequiredSource, Decl(inferenceDiscriminantOverlap.ts, 5, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 5, 40)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 5, 50)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 5, 65)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 5, 81)) + +declare const explicitUndefinedSource: { tag: "a"; value: 1 } | { tag: "b" | undefined; value: 2 }; +>explicitUndefinedSource : Symbol(explicitUndefinedSource, Decl(inferenceDiscriminantOverlap.ts, 6, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 6, 40)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 6, 50)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 6, 65)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 6, 87)) + +declare const optionalNeverSource: { tag: "a"; value: 1 } | { tag?: never; value: 2 }; +>optionalNeverSource : Symbol(optionalNeverSource, Decl(inferenceDiscriminantOverlap.ts, 7, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 7, 36)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 7, 46)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 7, 61)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 7, 74)) + +declare const indexedSource: +>indexedSource : Symbol(indexedSource, Decl(inferenceDiscriminantOverlap.ts, 9, 13)) + + | { tag: "a"; value: "a" } +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 10, 7)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 10, 17)) + + | { tag?: "a"; value: "a" } +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 11, 7)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 11, 18)) + + | { [key: string]: "b"; value: "b" }; +>key : Symbol(key, Decl(inferenceDiscriminantOverlap.ts, 12, 9)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 12, 27)) + +declare const requiredPropertySource: +>requiredPropertySource : Symbol(requiredPropertySource, Decl(inferenceDiscriminantOverlap.ts, 13, 13)) + + | { tag: "a"; value: "a" } +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 14, 7)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 14, 17)) + + | { [key: string]: "b"; tag: "b"; value: "b" }; +>key : Symbol(key, Decl(inferenceDiscriminantOverlap.ts, 15, 9)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 15, 27)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 15, 37)) + +declare const optionalPropertySource: +>optionalPropertySource : Symbol(optionalPropertySource, Decl(inferenceDiscriminantOverlap.ts, 16, 13)) + + | { tag: "a"; value: "a" } +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 17, 7)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 17, 17)) + + | { [key: string]: "a" | "b" | undefined; tag?: "a"; value: "b" }; +>key : Symbol(key, Decl(inferenceDiscriminantOverlap.ts, 18, 9)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 18, 45)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 18, 56)) + +declare function inferOptionalSource(value: { tag?: "a"; value: T }): T; +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 20, 37)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 20, 40)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 20, 48)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 20, 59)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 20, 37)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 20, 37)) + +const validOptional = inferOptionalSource(validOptionalSource); +>validOptional : Symbol(validOptional, Decl(inferenceDiscriminantOverlap.ts, 21, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>validOptionalSource : Symbol(validOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 0, 13)) + +const mixedOptional = inferOptionalSource(mixedOptionalSource); +>mixedOptional : Symbol(mixedOptional, Decl(inferenceDiscriminantOverlap.ts, 22, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>mixedOptionalSource : Symbol(mixedOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 1, 13)) + +const matchingOptional = inferOptionalSource(matchingOptionalSource); +>matchingOptional : Symbol(matchingOptional, Decl(inferenceDiscriminantOverlap.ts, 23, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>matchingOptionalSource : Symbol(matchingOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 2, 13)) + +const requiredMismatch = inferOptionalSource(requiredMismatchSource); +>requiredMismatch : Symbol(requiredMismatch, Decl(inferenceDiscriminantOverlap.ts, 24, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>requiredMismatchSource : Symbol(requiredMismatchSource, Decl(inferenceDiscriminantOverlap.ts, 3, 13)) + +const requiredUndefined = inferOptionalSource(undefinedRequiredSource); +>requiredUndefined : Symbol(requiredUndefined, Decl(inferenceDiscriminantOverlap.ts, 25, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>undefinedRequiredSource : Symbol(undefinedRequiredSource, Decl(inferenceDiscriminantOverlap.ts, 5, 13)) + +const explicitUndefined = inferOptionalSource(explicitUndefinedSource); +>explicitUndefined : Symbol(explicitUndefined, Decl(inferenceDiscriminantOverlap.ts, 26, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>explicitUndefinedSource : Symbol(explicitUndefinedSource, Decl(inferenceDiscriminantOverlap.ts, 6, 13)) + +const optionalNever = inferOptionalSource(optionalNeverSource); +>optionalNever : Symbol(optionalNever, Decl(inferenceDiscriminantOverlap.ts, 27, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>optionalNeverSource : Symbol(optionalNeverSource, Decl(inferenceDiscriminantOverlap.ts, 7, 13)) + +const indexedOptional = inferOptionalSource(indexedSource); // error +>indexedOptional : Symbol(indexedOptional, Decl(inferenceDiscriminantOverlap.ts, 28, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>indexedSource : Symbol(indexedSource, Decl(inferenceDiscriminantOverlap.ts, 9, 13)) + +const declaredOptional = inferOptionalSource(optionalPropertySource); // error +>declaredOptional : Symbol(declaredOptional, Decl(inferenceDiscriminantOverlap.ts, 29, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>optionalPropertySource : Symbol(optionalPropertySource, Decl(inferenceDiscriminantOverlap.ts, 16, 13)) + +const declaredRequired = inferOptionalSource(requiredPropertySource); // error +>declaredRequired : Symbol(declaredRequired, Decl(inferenceDiscriminantOverlap.ts, 30, 5)) +>inferOptionalSource : Symbol(inferOptionalSource, Decl(inferenceDiscriminantOverlap.ts, 18, 70)) +>requiredPropertySource : Symbol(requiredPropertySource, Decl(inferenceDiscriminantOverlap.ts, 13, 13)) + +declare function inferRequiredSource(value: { tag: "a"; value: T }): T; +>inferRequiredSource : Symbol(inferRequiredSource, Decl(inferenceDiscriminantOverlap.ts, 30, 69)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 32, 37)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 32, 40)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 32, 48)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 32, 58)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 32, 37)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 32, 37)) + +const partiallyMatching = inferRequiredSource(partiallyMatchingSource); +>partiallyMatching : Symbol(partiallyMatching, Decl(inferenceDiscriminantOverlap.ts, 33, 5)) +>inferRequiredSource : Symbol(inferRequiredSource, Decl(inferenceDiscriminantOverlap.ts, 30, 69)) +>partiallyMatchingSource : Symbol(partiallyMatchingSource, Decl(inferenceDiscriminantOverlap.ts, 4, 13)) + +const indexedRequired = inferRequiredSource(indexedSource); // error +>indexedRequired : Symbol(indexedRequired, Decl(inferenceDiscriminantOverlap.ts, 34, 5)) +>inferRequiredSource : Symbol(inferRequiredSource, Decl(inferenceDiscriminantOverlap.ts, 30, 69)) +>indexedSource : Symbol(indexedSource, Decl(inferenceDiscriminantOverlap.ts, 9, 13)) + +declare function makeOptional(): { tag?: "a"; value: T }; +>makeOptional : Symbol(makeOptional, Decl(inferenceDiscriminantOverlap.ts, 34, 59)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 36, 30)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 36, 43)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 36, 54)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 36, 30)) + +export function optionalContext(): { tag: "a"; value: 1 } | { tag?: "b"; value: 2 } { +>optionalContext : Symbol(optionalContext, Decl(inferenceDiscriminantOverlap.ts, 36, 66)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 37, 36)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 37, 46)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 37, 61)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 37, 72)) + + return makeOptional(); +>makeOptional : Symbol(makeOptional, Decl(inferenceDiscriminantOverlap.ts, 34, 59)) +} + +declare function inferOptionalTargets(value: { tag: "a"; value: A } | { tag?: "b"; value: B }): [A, B]; +>inferOptionalTargets : Symbol(inferOptionalTargets, Decl(inferenceDiscriminantOverlap.ts, 39, 1)) +>A : Symbol(A, Decl(inferenceDiscriminantOverlap.ts, 41, 38)) +>B : Symbol(B, Decl(inferenceDiscriminantOverlap.ts, 41, 40)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 41, 44)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 41, 52)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 41, 62)) +>A : Symbol(A, Decl(inferenceDiscriminantOverlap.ts, 41, 38)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 41, 77)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 41, 88)) +>B : Symbol(B, Decl(inferenceDiscriminantOverlap.ts, 41, 40)) +>A : Symbol(A, Decl(inferenceDiscriminantOverlap.ts, 41, 38)) +>B : Symbol(B, Decl(inferenceDiscriminantOverlap.ts, 41, 40)) + +declare const optionalInput: { tag?: "a"; value: 42 }; +>optionalInput : Symbol(optionalInput, Decl(inferenceDiscriminantOverlap.ts, 42, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 42, 30)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 42, 41)) + +declare const optionalNeverInput: { tag?: never; value: 42 }; +>optionalNeverInput : Symbol(optionalNeverInput, Decl(inferenceDiscriminantOverlap.ts, 43, 13)) +>tag : Symbol(tag, Decl(inferenceDiscriminantOverlap.ts, 43, 35)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 43, 48)) + +const optionalTargetInference = inferOptionalTargets(optionalInput); +>optionalTargetInference : Symbol(optionalTargetInference, Decl(inferenceDiscriminantOverlap.ts, 44, 5)) +>inferOptionalTargets : Symbol(inferOptionalTargets, Decl(inferenceDiscriminantOverlap.ts, 39, 1)) +>optionalInput : Symbol(optionalInput, Decl(inferenceDiscriminantOverlap.ts, 42, 13)) + +const optionalNeverTargetInference = inferOptionalTargets(optionalNeverInput); +>optionalNeverTargetInference : Symbol(optionalNeverTargetInference, Decl(inferenceDiscriminantOverlap.ts, 45, 5)) +>inferOptionalTargets : Symbol(inferOptionalTargets, Decl(inferenceDiscriminantOverlap.ts, 39, 1)) +>optionalNeverInput : Symbol(optionalNeverInput, Decl(inferenceDiscriminantOverlap.ts, 43, 13)) + +// Return type inference runs with the contextual type as the source and the declared +// return type as the target, so assignability has to hold the other way around. +declare function makeTagged(value: T): { kind: "a"; value: T }; +>makeTagged : Symbol(makeTagged, Decl(inferenceDiscriminantOverlap.ts, 45, 78)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 49, 28)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 49, 37)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 49, 28)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 49, 49)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 49, 60)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 49, 28)) + +declare function makeOptionalTagged(value: T): { kind?: "a"; value: T }; +>makeOptionalTagged : Symbol(makeOptionalTagged, Decl(inferenceDiscriminantOverlap.ts, 49, 72)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 50, 36)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 50, 45)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 50, 36)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 50, 57)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 50, 69)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 50, 36)) + +declare function makeUnionTagged(value: T): { kind: "a" | undefined; value: T }; +>makeUnionTagged : Symbol(makeUnionTagged, Decl(inferenceDiscriminantOverlap.ts, 50, 81)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 51, 33)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 51, 42)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 51, 33)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 51, 54)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 51, 77)) +>T : Symbol(T, Decl(inferenceDiscriminantOverlap.ts, 51, 33)) + +export function broadContext(): { kind: string; value: string[] } | { kind: "a"; value: number } { +>broadContext : Symbol(broadContext, Decl(inferenceDiscriminantOverlap.ts, 51, 89)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 53, 33)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 53, 47)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 53, 69)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 53, 80)) + + return makeTagged([]); +>makeTagged : Symbol(makeTagged, Decl(inferenceDiscriminantOverlap.ts, 45, 78)) +} +export function partialTagContext(): { kind: "a" | "b"; value: string[] } | { kind: "a"; value: number } { +>partialTagContext : Symbol(partialTagContext, Decl(inferenceDiscriminantOverlap.ts, 55, 1)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 56, 38)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 56, 55)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 56, 77)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 56, 88)) + + return makeTagged([]); +>makeTagged : Symbol(makeTagged, Decl(inferenceDiscriminantOverlap.ts, 45, 78)) +} +export function unionTagContext(): { kind?: "a"; value: string[] } | { kind: "a"; value: number } { +>unionTagContext : Symbol(unionTagContext, Decl(inferenceDiscriminantOverlap.ts, 58, 1)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 59, 36)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 59, 48)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 59, 70)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 59, 81)) + + return makeUnionTagged([]); +>makeUnionTagged : Symbol(makeUnionTagged, Decl(inferenceDiscriminantOverlap.ts, 50, 81)) +} +export function indexedContext(): +>indexedContext : Symbol(indexedContext, Decl(inferenceDiscriminantOverlap.ts, 61, 1)) + + | { [key: string]: string | string[]; value: string[] } +>key : Symbol(key, Decl(inferenceDiscriminantOverlap.ts, 63, 9)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 63, 41)) + + | { kind: "a"; value: number } +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 64, 7)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 64, 18)) + + | { kind: "b"; value: boolean } { +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 65, 7)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 65, 18)) + + return makeOptionalTagged([]); +>makeOptionalTagged : Symbol(makeOptionalTagged, Decl(inferenceDiscriminantOverlap.ts, 49, 72)) +} + +declare function makeEither(a: A, b: B): { kind: "a"; value: A } | { kind: "b"; value: B }; +>makeEither : Symbol(makeEither, Decl(inferenceDiscriminantOverlap.ts, 67, 1)) +>A : Symbol(A, Decl(inferenceDiscriminantOverlap.ts, 69, 28)) +>B : Symbol(B, Decl(inferenceDiscriminantOverlap.ts, 69, 36)) +>a : Symbol(a, Decl(inferenceDiscriminantOverlap.ts, 69, 46)) +>A : Symbol(A, Decl(inferenceDiscriminantOverlap.ts, 69, 28)) +>b : Symbol(b, Decl(inferenceDiscriminantOverlap.ts, 69, 51)) +>B : Symbol(B, Decl(inferenceDiscriminantOverlap.ts, 69, 36)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 69, 60)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 69, 71)) +>A : Symbol(A, Decl(inferenceDiscriminantOverlap.ts, 69, 28)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 69, 86)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 69, 97)) +>B : Symbol(B, Decl(inferenceDiscriminantOverlap.ts, 69, 36)) + +export function eitherContext(): { kind: "a"; value: string[] } | { kind: "b"; value: number[] } { +>eitherContext : Symbol(eitherContext, Decl(inferenceDiscriminantOverlap.ts, 69, 109)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 70, 34)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 70, 45)) +>kind : Symbol(kind, Decl(inferenceDiscriminantOverlap.ts, 70, 67)) +>value : Symbol(value, Decl(inferenceDiscriminantOverlap.ts, 70, 78)) + + return makeEither([], []); +>makeEither : Symbol(makeEither, Decl(inferenceDiscriminantOverlap.ts, 67, 1)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=true).types b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=true).types new file mode 100644 index 0000000000000..9302ce41820d2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminantOverlap(exactoptionalpropertytypes=true).types @@ -0,0 +1,331 @@ +//// [tests/cases/compiler/inferenceDiscriminantOverlap.ts] //// + +=== inferenceDiscriminantOverlap.ts === +declare const validOptionalSource: { tag: "a"; value: 1 } | { tag?: "a"; value: 2 }; +>validOptionalSource : { tag: "a"; value: 1; } | { tag?: "a"; value: 2; } +>tag : "a" +>value : 1 +>tag : "a" | undefined +>value : 2 + +declare const mixedOptionalSource: { tag: "a"; value: 1 } | { tag?: "b"; value: 2 }; +>mixedOptionalSource : { tag: "a"; value: 1; } | { tag?: "b"; value: 2; } +>tag : "a" +>value : 1 +>tag : "b" | undefined +>value : 2 + +declare const matchingOptionalSource: { tag: "a"; value: 1 } | { tag?: "a"; value: 2 } | { tag: "b"; value: 3 }; +>matchingOptionalSource : { tag: "a"; value: 1; } | { tag?: "a"; value: 2; } | { tag: "b"; value: 3; } +>tag : "a" +>value : 1 +>tag : "a" | undefined +>value : 2 +>tag : "b" +>value : 3 + +declare const requiredMismatchSource: { tag: "a"; value: 1 } | { tag: "b"; value: 2 }; +>requiredMismatchSource : { tag: "a"; value: 1; } | { tag: "b"; value: 2; } +>tag : "a" +>value : 1 +>tag : "b" +>value : 2 + +declare const partiallyMatchingSource: { tag: "a" | "b"; value: 1 } | { tag: "b"; value: 2 }; +>partiallyMatchingSource : { tag: "a" | "b"; value: 1; } | { tag: "b"; value: 2; } +>tag : "a" | "b" +>value : 1 +>tag : "b" +>value : 2 + +declare const undefinedRequiredSource: { tag: "a"; value: 1 } | { tag: undefined; value: 2 }; +>undefinedRequiredSource : { tag: "a"; value: 1; } | { tag: undefined; value: 2; } +>tag : "a" +>value : 1 +>tag : undefined +>value : 2 + +declare const explicitUndefinedSource: { tag: "a"; value: 1 } | { tag: "b" | undefined; value: 2 }; +>explicitUndefinedSource : { tag: "a"; value: 1; } | { tag: "b" | undefined; value: 2; } +>tag : "a" +>value : 1 +>tag : "b" | undefined +>value : 2 + +declare const optionalNeverSource: { tag: "a"; value: 1 } | { tag?: never; value: 2 }; +>optionalNeverSource : { tag: "a"; value: 1; } | { tag?: never; value: 2; } +>tag : "a" +>value : 1 +>tag : undefined +>value : 2 + +declare const indexedSource: +>indexedSource : { tag: "a"; value: "a"; } | { tag?: "a"; value: "a"; } | { [key: string]: "b"; value: "b"; } + + | { tag: "a"; value: "a" } +>tag : "a" +>value : "a" + + | { tag?: "a"; value: "a" } +>tag : "a" | undefined +>value : "a" + + | { [key: string]: "b"; value: "b" }; +>key : string +>value : "b" + +declare const requiredPropertySource: +>requiredPropertySource : { tag: "a"; value: "a"; } | { [key: string]: "b"; tag: "b"; value: "b"; } + + | { tag: "a"; value: "a" } +>tag : "a" +>value : "a" + + | { [key: string]: "b"; tag: "b"; value: "b" }; +>key : string +>tag : "b" +>value : "b" + +declare const optionalPropertySource: +>optionalPropertySource : { tag: "a"; value: "a"; } | { [key: string]: "a" | "b" | undefined; tag?: "a"; value: "b"; } + + | { tag: "a"; value: "a" } +>tag : "a" +>value : "a" + + | { [key: string]: "a" | "b" | undefined; tag?: "a"; value: "b" }; +>key : string +>tag : "a" | undefined +>value : "b" + +declare function inferOptionalSource(value: { tag?: "a"; value: T }): T; +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>value : { tag?: "a"; value: T; } +>tag : "a" | undefined +>value : T + +const validOptional = inferOptionalSource(validOptionalSource); +>validOptional : 1 | 2 +>inferOptionalSource(validOptionalSource) : 1 | 2 +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>validOptionalSource : { tag: "a"; value: 1; } | { tag?: "a"; value: 2; } + +const mixedOptional = inferOptionalSource(mixedOptionalSource); +>mixedOptional : 1 | 2 +>inferOptionalSource(mixedOptionalSource) : 1 | 2 +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>mixedOptionalSource : { tag: "a"; value: 1; } | { tag?: "b"; value: 2; } + +const matchingOptional = inferOptionalSource(matchingOptionalSource); +>matchingOptional : 1 | 2 +>inferOptionalSource(matchingOptionalSource) : 1 | 2 +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>matchingOptionalSource : { tag: "a"; value: 1; } | { tag?: "a"; value: 2; } | { tag: "b"; value: 3; } + +const requiredMismatch = inferOptionalSource(requiredMismatchSource); +>requiredMismatch : 1 +>inferOptionalSource(requiredMismatchSource) : 1 +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>requiredMismatchSource : { tag: "a"; value: 1; } | { tag: "b"; value: 2; } + +const requiredUndefined = inferOptionalSource(undefinedRequiredSource); +>requiredUndefined : 1 | 2 +>inferOptionalSource(undefinedRequiredSource) : 1 | 2 +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>undefinedRequiredSource : { tag: "a"; value: 1; } | { tag: undefined; value: 2; } + +const explicitUndefined = inferOptionalSource(explicitUndefinedSource); +>explicitUndefined : 1 | 2 +>inferOptionalSource(explicitUndefinedSource) : 1 | 2 +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>explicitUndefinedSource : { tag: "a"; value: 1; } | { tag: "b" | undefined; value: 2; } + +const optionalNever = inferOptionalSource(optionalNeverSource); +>optionalNever : 1 | 2 +>inferOptionalSource(optionalNeverSource) : 1 | 2 +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>optionalNeverSource : { tag: "a"; value: 1; } | { tag?: never; value: 2; } + +const indexedOptional = inferOptionalSource(indexedSource); // error +>indexedOptional : "a" | "b" +>inferOptionalSource(indexedSource) : "a" | "b" +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>indexedSource : { tag: "a"; value: "a"; } | { tag?: "a"; value: "a"; } | { [key: string]: "b"; value: "b"; } + +const declaredOptional = inferOptionalSource(optionalPropertySource); // error +>declaredOptional : "a" | "b" +>inferOptionalSource(optionalPropertySource) : "a" | "b" +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>optionalPropertySource : { tag: "a"; value: "a"; } | { [key: string]: "a" | "b" | undefined; tag?: "a"; value: "b"; } + +const declaredRequired = inferOptionalSource(requiredPropertySource); // error +>declaredRequired : "a" +>inferOptionalSource(requiredPropertySource) : "a" +>inferOptionalSource : (value: { tag?: "a"; value: T; }) => T +>requiredPropertySource : { tag: "a"; value: "a"; } | { [key: string]: "b"; tag: "b"; value: "b"; } + +declare function inferRequiredSource(value: { tag: "a"; value: T }): T; +>inferRequiredSource : (value: { tag: "a"; value: T; }) => T +>value : { tag: "a"; value: T; } +>tag : "a" +>value : T + +const partiallyMatching = inferRequiredSource(partiallyMatchingSource); +>partiallyMatching : 1 +>inferRequiredSource(partiallyMatchingSource) : 1 +>inferRequiredSource : (value: { tag: "a"; value: T; }) => T +>partiallyMatchingSource : { tag: "a" | "b"; value: 1; } | { tag: "b"; value: 2; } + +const indexedRequired = inferRequiredSource(indexedSource); // error +>indexedRequired : "a" +>inferRequiredSource(indexedSource) : "a" +>inferRequiredSource : (value: { tag: "a"; value: T; }) => T +>indexedSource : { tag: "a"; value: "a"; } | { tag?: "a"; value: "a"; } | { [key: string]: "b"; value: "b"; } + +declare function makeOptional(): { tag?: "a"; value: T }; +>makeOptional : () => { tag?: "a"; value: T; } +>tag : "a" | undefined +>value : T + +export function optionalContext(): { tag: "a"; value: 1 } | { tag?: "b"; value: 2 } { +>optionalContext : () => { tag: "a"; value: 1; } | { tag?: "b"; value: 2; } +>tag : "a" +>value : 1 +>tag : "b" | undefined +>value : 2 + + return makeOptional(); +>makeOptional() : { tag?: "a"; value: 1 | 2; } +>makeOptional : () => { tag?: "a"; value: T; } +} + +declare function inferOptionalTargets(value: { tag: "a"; value: A } | { tag?: "b"; value: B }): [A, B]; +>inferOptionalTargets : (value: { tag: "a"; value: A; } | { tag?: "b"; value: B; }) => [A, B] +>value : { tag: "a"; value: A; } | { tag?: "b"; value: B; } +>tag : "a" +>value : A +>tag : "b" | undefined +>value : B + +declare const optionalInput: { tag?: "a"; value: 42 }; +>optionalInput : { tag?: "a"; value: 42; } +>tag : "a" | undefined +>value : 42 + +declare const optionalNeverInput: { tag?: never; value: 42 }; +>optionalNeverInput : { tag?: never; value: 42; } +>tag : undefined +>value : 42 + +const optionalTargetInference = inferOptionalTargets(optionalInput); +>optionalTargetInference : [42, 42] +>inferOptionalTargets(optionalInput) : [42, 42] +>inferOptionalTargets : (value: { tag: "a"; value: A; } | { tag?: "b"; value: B; }) => [A, B] +>optionalInput : { tag?: "a"; value: 42; } + +const optionalNeverTargetInference = inferOptionalTargets(optionalNeverInput); +>optionalNeverTargetInference : [42, 42] +>inferOptionalTargets(optionalNeverInput) : [42, 42] +>inferOptionalTargets : (value: { tag: "a"; value: A; } | { tag?: "b"; value: B; }) => [A, B] +>optionalNeverInput : { tag?: never; value: 42; } + +// Return type inference runs with the contextual type as the source and the declared +// return type as the target, so assignability has to hold the other way around. +declare function makeTagged(value: T): { kind: "a"; value: T }; +>makeTagged : (value: T) => { kind: "a"; value: T; } +>value : T +>kind : "a" +>value : T + +declare function makeOptionalTagged(value: T): { kind?: "a"; value: T }; +>makeOptionalTagged : (value: T) => { kind?: "a"; value: T; } +>value : T +>kind : "a" | undefined +>value : T + +declare function makeUnionTagged(value: T): { kind: "a" | undefined; value: T }; +>makeUnionTagged : (value: T) => { kind: "a" | undefined; value: T; } +>value : T +>kind : "a" | undefined +>value : T + +export function broadContext(): { kind: string; value: string[] } | { kind: "a"; value: number } { +>broadContext : () => { kind: string; value: string[]; } | { kind: "a"; value: number; } +>kind : string +>value : string[] +>kind : "a" +>value : number + + return makeTagged([]); +>makeTagged([]) : { kind: "a"; value: []; } +>makeTagged : (value: T) => { kind: "a"; value: T; } +>[] : [] +} +export function partialTagContext(): { kind: "a" | "b"; value: string[] } | { kind: "a"; value: number } { +>partialTagContext : () => { kind: "a" | "b"; value: string[]; } | { kind: "a"; value: number; } +>kind : "a" | "b" +>value : string[] +>kind : "a" +>value : number + + return makeTagged([]); +>makeTagged([]) : { kind: "a"; value: []; } +>makeTagged : (value: T) => { kind: "a"; value: T; } +>[] : [] +} +export function unionTagContext(): { kind?: "a"; value: string[] } | { kind: "a"; value: number } { +>unionTagContext : () => { kind?: "a"; value: string[]; } | { kind: "a"; value: number; } +>kind : "a" | undefined +>value : string[] +>kind : "a" +>value : number + + return makeUnionTagged([]); +>makeUnionTagged([]) : { kind: "a" | undefined; value: []; } +>makeUnionTagged : (value: T) => { kind: "a" | undefined; value: T; } +>[] : [] +} +export function indexedContext(): +>indexedContext : () => { [key: string]: string | string[]; value: string[]; } | { kind: "a"; value: number; } | { kind: "b"; value: boolean; } + + | { [key: string]: string | string[]; value: string[] } +>key : string +>value : string[] + + | { kind: "a"; value: number } +>kind : "a" +>value : number + + | { kind: "b"; value: boolean } { +>kind : "b" +>value : boolean + + return makeOptionalTagged([]); +>makeOptionalTagged([]) : { kind?: "a"; value: []; } +>makeOptionalTagged : (value: T) => { kind?: "a"; value: T; } +>[] : [] +} + +declare function makeEither(a: A, b: B): { kind: "a"; value: A } | { kind: "b"; value: B }; +>makeEither : (a: A, b: B) => { kind: "a"; value: A; } | { kind: "b"; value: B; } +>a : A +>b : B +>kind : "a" +>value : A +>kind : "b" +>value : B + +export function eitherContext(): { kind: "a"; value: string[] } | { kind: "b"; value: number[] } { +>eitherContext : () => { kind: "a"; value: string[]; } | { kind: "b"; value: number[]; } +>kind : "a" +>value : string[] +>kind : "b" +>value : number[] + + return makeEither([], []); +>makeEither([], []) : { kind: "a"; value: []; } | { kind: "b"; value: []; } +>makeEither : (a: A, b: B) => { kind: "a"; value: A; } | { kind: "b"; value: B; } +>[] : [] +>[] : [] +} + diff --git a/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=false).errors.txt b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=false).errors.txt new file mode 100644 index 0000000000000..991793bf5c43a --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=false).errors.txt @@ -0,0 +1,299 @@ +inferenceDiscriminatedUnions1.ts(52,17): error TS2345: Argument of type '{ kind: "b"; value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: string; }'. + Type '{ kind: "b"; value: number; }' is not assignable to type '{ kind: "a"; value: string; }'. + Types of property 'kind' are incompatible. + Type '"b"' is not assignable to type '"a"'. +inferenceDiscriminatedUnions1.ts(53,17): error TS2345: Argument of type '{ kind: string; value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: number; }'. + Type '{ kind: string; value: number; }' is not assignable to type '{ kind: "a"; value: number; }'. + Types of property 'kind' are incompatible. + Type 'string' is not assignable to type '"a"'. +inferenceDiscriminatedUnions1.ts(54,26): error TS2345: Argument of type '{ kind: number; value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: string; }'. + Type '{ kind: number; value: number; }' is not assignable to type '{ kind: "a"; value: string; }'. + Types of property 'kind' are incompatible. + Type 'number' is not assignable to type '"a"'. +inferenceDiscriminatedUnions1.ts(55,17): error TS2345: Argument of type '{ value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: number; }'. + Property 'kind' is missing in type '{ value: number; }' but required in type '{ kind: "a"; value: number; }'. +inferenceDiscriminatedUnions1.ts(58,16): error TS2345: Argument of type '{ kind: "a"; sub: 2; value: string; } | { kind: "b"; sub: 1; value: number; }' is not assignable to parameter of type '{ kind: "a"; sub: 1; value: string; }'. + Type '{ kind: "a"; sub: 2; value: string; }' is not assignable to type '{ kind: "a"; sub: 1; value: string; }'. + Types of property 'sub' are incompatible. + Type '2' is not assignable to type '1'. +inferenceDiscriminatedUnions1.ts(61,32): error TS2345: Argument of type '{ kind: "a"; sub: 2; value: string; } | { kind: "b"; sub: 1; value: number; }' is not assignable to parameter of type '{ sub: 1; kind: "a"; value: number; }'. + Type '{ kind: "a"; sub: 2; value: string; }' is not assignable to type '{ sub: 1; kind: "a"; value: number; }'. + Types of property 'sub' are incompatible. + Type '2' is not assignable to type '1'. +inferenceDiscriminatedUnions1.ts(64,20): error TS2345: Argument of type '{ kind: K.B; value: number; } | { kind: K.A; value: string; }' is not assignable to parameter of type '{ kind: K.A; value: string; }'. + Type '{ kind: K.B; value: number; }' is not assignable to type '{ kind: K.A; value: string; }'. + Types of property 'kind' are incompatible. + Type 'K.B' is not assignable to type 'K.A'. +inferenceDiscriminatedUnions1.ts(67,20): error TS2345: Argument of type 'Err | Ok' is not assignable to parameter of type '{ ok: boolean; value: number; }'. + Type 'Ok' is not assignable to type '{ ok: boolean; value: number; }'. + Types of property 'value' are incompatible. + Type 'string' is not assignable to type 'number'. +inferenceDiscriminatedUnions1.ts(84,5): error TS2322: Type '{ kind: "other"; value: string[] | number[]; }' is not assignable to type 'Failure | Success'. + Type '{ kind: "other"; value: string[] | number[]; }' is not assignable to type 'Success'. + Types of property 'kind' are incompatible. + Type '"other"' is not assignable to type '"success"'. +inferenceDiscriminatedUnions1.ts(93,5): error TS2322: Type 'OptionalOk' is not assignable to type 'MaybeErr | OptionalOk'. + Type 'OptionalOk' is not assignable to type 'OptionalOk'. + The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. +inferenceDiscriminatedUnions1.ts(101,5): error TS2322: Type 'OptionalOk' is not assignable to type 'AlwaysUndefinedErr | OptionalOk'. + Type 'OptionalOk' is not assignable to type 'OptionalOk'. + The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. +inferenceDiscriminatedUnions1.ts(110,5): error TS2322: Type 'ExplicitOptionalOk' is not assignable to type 'AlwaysUndefinedErr | ExplicitOptionalOk'. + Type 'ExplicitOptionalOk' is not assignable to type 'ExplicitOptionalOk'. + The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. +inferenceDiscriminatedUnions1.ts(120,5): error TS2322: Type 'UndefinedOk' is not assignable to type 'MaybeErr | UndefinedOk'. + Type 'UndefinedOk' is not assignable to type 'UndefinedOk'. + The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. +inferenceDiscriminatedUnions1.ts(131,43): error TS2345: Argument of type '{ type: string; value: number; }' is not assignable to parameter of type '{ type: "a"; value: number; } | { type: "b"; value: number; }'. + Type '{ type: string; value: number; }' is not assignable to type '{ type: "b"; value: number; }'. + Types of property 'type' are incompatible. + Type 'string' is not assignable to type '"b"'. +inferenceDiscriminatedUnions1.ts(132,45): error TS2345: Argument of type '{ value: number; }' is not assignable to parameter of type '{ type: "a"; value: number; } | { type: "b"; value: number; }'. + Property 'type' is missing in type '{ value: number; }' but required in type '{ type: "b"; value: number; }'. +inferenceDiscriminatedUnions1.ts(146,52): error TS2345: Argument of type '{ type: "a"; sub: 2; value: number; }' is not assignable to parameter of type '{ type: "a"; sub: 1; value: number; } | { type: "b"; sub: 2; value: unknown; }'. + Types of property 'sub' are incompatible. + Type '2' is not assignable to type '1'. +inferenceDiscriminatedUnions1.ts(147,66): error TS2345: Argument of type '{ sub: 2; type: "a"; value: number; }' is not assignable to parameter of type '{ type: "a"; sub: 1; value: unknown; } | { type: "b"; sub: 2; value: number; }'. + Types of property 'type' are incompatible. + Type '"a"' is not assignable to type '"b"'. +inferenceDiscriminatedUnions1.ts(150,68): error TS2345: Argument of type '{ type: "a"; sub: 2; value: number; }' is not assignable to parameter of type '{ sub: 1; type: "a"; value: number; } | { sub: 2; type: "b"; value: unknown; }'. + Types of property 'sub' are incompatible. + Type '2' is not assignable to type '1'. + + +==== inferenceDiscriminatedUnions1.ts (18 errors) ==== + type Ok = { ok: true; value: T }; + type Err = { ok: false; value: E }; + type ErrShape = { ok: false; value: string }; + type OkShape = { ok: true; value: string[] }; + enum K { A, B } + type Success = { kind: "success"; value: T }; + type Failure = { kind: "failure"; value: E }; + type Accepted = { kind: 1; value: T }; + type Rejected = { kind: 0; value: E }; + type OptionalOk = { ok?: true; value: T }; + type MaybeErr = { ok?: false; value: E }; + type ExplicitOptionalOk = { ok?: true | undefined; value: T }; + type UnionOk = { ok: true | undefined; value: T }; + type AlwaysUndefinedErr = { ok: undefined; value: E }; + type UndefinedOk = { ok: undefined; value: T }; + type Tagged = { type: "a"; value: A } | { type: "b"; value: B }; + + declare const u1: { kind: "b"; value: number } | { kind: "a"; value: string }; + declare const u2: { kind: string; value: number } | { kind: "a"; value: string }; + declare const broadTag: { kind: number; value: number } | { kind: "a"; value: string }; + declare const u3: { value: number } | { kind: "a"; value: string }; + declare const u4: { kind: "a"; sub: 2; value: string } | { kind: "b"; sub: 1; value: number }; + declare const u5: { kind: K.B; value: number } | { kind: K.A; value: string }; + declare const u6: Err | Ok; + declare const taggedSource: Tagged; + declare const reversedTaggedSource: { type: "b"; value: number } | { type: "a"; value: string }; + declare const broadSourceTag: { type: string; value: number }; + declare const missingTag: { value: number }; + declare const optionalTag: { type?: "a"; value: string }; + + declare function ok(value: T): Ok; + export function aliasTarget(): ErrShape | OkShape { return ok([]); } + + export function f(): Ok | Err { + return ok([]); + } + + export function optionalSource(): Ok | MaybeErr { + return ok([]); + } + + declare function okInline(value: T): { ok: true; value: T }; + export function inlineTarget(): ErrShape | OkShape { return okInline([]); } + + export function inlineTargetReversed(): OkShape | ErrShape { return okInline([]); } + + declare function on(handler: (e: { kind: "a"; value: T }) => void): T; + const r1 = on((e: { kind: "a"; value: string } | { kind: "b"; value: number }) => {}); + const r2 = on((e: { kind: "b"; value: number } | { kind: "a"; value: string }) => {}); + + declare function pick(x: { kind: "a"; value: T }): T; + const r3 = pick(u1); + ~~ +!!! error TS2345: Argument of type '{ kind: "b"; value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: string; }'. +!!! error TS2345: Type '{ kind: "b"; value: number; }' is not assignable to type '{ kind: "a"; value: string; }'. +!!! error TS2345: Types of property 'kind' are incompatible. +!!! error TS2345: Type '"b"' is not assignable to type '"a"'. + const r4 = pick(u2); + ~~ +!!! error TS2345: Argument of type '{ kind: string; value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: number; }'. +!!! error TS2345: Type '{ kind: string; value: number; }' is not assignable to type '{ kind: "a"; value: number; }'. +!!! error TS2345: Types of property 'kind' are incompatible. +!!! error TS2345: Type 'string' is not assignable to type '"a"'. + const broadResult = pick(broadTag); + ~~~~~~~~ +!!! error TS2345: Argument of type '{ kind: number; value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: string; }'. +!!! error TS2345: Type '{ kind: number; value: number; }' is not assignable to type '{ kind: "a"; value: string; }'. +!!! error TS2345: Types of property 'kind' are incompatible. +!!! error TS2345: Type 'number' is not assignable to type '"a"'. + const r5 = pick(u3); + ~~ +!!! error TS2345: Argument of type '{ value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: number; }'. +!!! error TS2345: Property 'kind' is missing in type '{ value: number; }' but required in type '{ kind: "a"; value: number; }'. +!!! related TS2728 inferenceDiscriminatedUnions1.ts:51:31: 'kind' is declared here. + + declare function two(x: { kind: "a"; sub: 1; value: T }): T; + const r6 = two(u4); + ~~ +!!! error TS2345: Argument of type '{ kind: "a"; sub: 2; value: string; } | { kind: "b"; sub: 1; value: number; }' is not assignable to parameter of type '{ kind: "a"; sub: 1; value: string; }'. +!!! error TS2345: Type '{ kind: "a"; sub: 2; value: string; }' is not assignable to type '{ kind: "a"; sub: 1; value: string; }'. +!!! error TS2345: Types of property 'sub' are incompatible. +!!! error TS2345: Type '2' is not assignable to type '1'. + + declare function twoReversed(x: { sub: 1; kind: "a"; value: T }): T; + const r6Reversed = twoReversed(u4); + ~~ +!!! error TS2345: Argument of type '{ kind: "a"; sub: 2; value: string; } | { kind: "b"; sub: 1; value: number; }' is not assignable to parameter of type '{ sub: 1; kind: "a"; value: number; }'. +!!! error TS2345: Type '{ kind: "a"; sub: 2; value: string; }' is not assignable to type '{ sub: 1; kind: "a"; value: number; }'. +!!! error TS2345: Types of property 'sub' are incompatible. +!!! error TS2345: Type '2' is not assignable to type '1'. + + declare function enumTag(x: { kind: K.A; value: T }): T; + const r7 = enumTag(u5); + ~~ +!!! error TS2345: Argument of type '{ kind: K.B; value: number; } | { kind: K.A; value: string; }' is not assignable to parameter of type '{ kind: K.A; value: string; }'. +!!! error TS2345: Type '{ kind: K.B; value: number; }' is not assignable to type '{ kind: K.A; value: string; }'. +!!! error TS2345: Types of property 'kind' are incompatible. +!!! error TS2345: Type 'K.B' is not assignable to type 'K.A'. + + declare function boolTag(x: { ok: boolean; value: T }): T; + const r8 = boolTag(u6); + ~~ +!!! error TS2345: Argument of type 'Err | Ok' is not assignable to parameter of type '{ ok: boolean; value: number; }'. +!!! error TS2345: Type 'Ok' is not assignable to type '{ ok: boolean; value: number; }'. +!!! error TS2345: Types of property 'value' are incompatible. +!!! error TS2345: Type 'string' is not assignable to type 'number'. + + declare function wrap(value: T): { result: Ok }; + export function nested(): { result: ErrShape | OkShape } { return wrap([]); } + + declare function success(value: T): Success; + export function withStringTag(): Success | Failure { + return success([]); + } + + declare function accepted(value: T): Accepted; + export function withNumberTag(): Accepted | Rejected { + return accepted([]); + } + + declare function unmatched(): { kind: "other"; value: T }; + export function withUnmatchedTag(): Success | Failure { + return unmatched(); + ~~~~~~ +!!! error TS2322: Type '{ kind: "other"; value: string[] | number[]; }' is not assignable to type 'Failure | Success'. +!!! error TS2322: Type '{ kind: "other"; value: string[] | number[]; }' is not assignable to type 'Success'. +!!! error TS2322: Types of property 'kind' are incompatible. +!!! error TS2322: Type '"other"' is not assignable to type '"success"'. + } + + declare function optionalOk(value: T): OptionalOk; + export function optionalTarget(): OptionalOk | Err { + return optionalOk([]); + } + + export function bothOptional(): OptionalOk | MaybeErr { + return optionalOk([]); + ~~~~~~ +!!! error TS2322: Type 'OptionalOk' is not assignable to type 'MaybeErr | OptionalOk'. +!!! error TS2322: Type 'OptionalOk' is not assignable to type 'OptionalOk'. +!!! error TS2322: The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. + } + + export function missingSourceTag(): OptionalOk | { value: string } { + return optionalOk([]); + } + + export function undefinedSource(): OptionalOk | AlwaysUndefinedErr { + return optionalOk([]); + ~~~~~~ +!!! error TS2322: Type 'OptionalOk' is not assignable to type 'AlwaysUndefinedErr | OptionalOk'. +!!! error TS2322: Type 'OptionalOk' is not assignable to type 'OptionalOk'. +!!! error TS2322: The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. + } + + declare function explicitOptionalOk(value: T): ExplicitOptionalOk; + export function explicitUndefined(): ExplicitOptionalOk | Err { + return explicitOptionalOk([]); + } + + export function explicitUndefinedOverlap(): ExplicitOptionalOk | AlwaysUndefinedErr { + return explicitOptionalOk([]); + ~~~~~~ +!!! error TS2322: Type 'ExplicitOptionalOk' is not assignable to type 'AlwaysUndefinedErr | ExplicitOptionalOk'. +!!! error TS2322: Type 'ExplicitOptionalOk' is not assignable to type 'ExplicitOptionalOk'. +!!! error TS2322: The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. + } + + declare function unionOk(value: T): UnionOk; + export function requiredUnionTag(): UnionOk | Err { + return unionOk([]); + } + + declare function undefinedOk(value: T): UndefinedOk; + export function undefinedTarget(): UndefinedOk | MaybeErr { + return undefinedOk([]); + ~~~~~~ +!!! error TS2322: Type 'UndefinedOk' is not assignable to type 'MaybeErr | UndefinedOk'. +!!! error TS2322: Type 'UndefinedOk' is not assignable to type 'UndefinedOk'. +!!! error TS2322: The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. + } + + declare function inferTwoArguments(first: Tagged, second: Tagged): [A, B]; + const twoArguments = inferTwoArguments({ type: "a", value: 42 }, { type: "b", value: true }); + + declare function inferInlineUnion(value: { type: "a"; value: A } | { type: "b"; value: B }): [A, B]; + const oneArgument = inferInlineUnion({ type: "a", value: 42 }); + const unionArgument = inferInlineUnion(taggedSource); + const explicitUnionArgument = inferInlineUnion(taggedSource); + const reversedSourceUnion = inferInlineUnion(reversedTaggedSource); + const broadTargetUnion = inferInlineUnion(broadSourceTag); + ~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ type: string; value: number; }' is not assignable to parameter of type '{ type: "a"; value: number; } | { type: "b"; value: number; }'. +!!! error TS2345: Type '{ type: string; value: number; }' is not assignable to type '{ type: "b"; value: number; }'. +!!! error TS2345: Types of property 'type' are incompatible. +!!! error TS2345: Type 'string' is not assignable to type '"b"'. + const missingTargetUnion = inferInlineUnion(missingTag); + ~~~~~~~~~~ +!!! error TS2345: Argument of type '{ value: number; }' is not assignable to parameter of type '{ type: "a"; value: number; } | { type: "b"; value: number; }'. +!!! error TS2345: Property 'type' is missing in type '{ value: number; }' but required in type '{ type: "b"; value: number; }'. +!!! related TS2728 inferenceDiscriminatedUnions1.ts:126:76: 'type' is declared here. + + declare function inferUnionWithFallback(value: T | Tagged): [T, A, B]; + const nakedTypeParameter = inferUnionWithFallback({ type: "a", value: 42 }); + + declare function inferNoInferOverloads(first: Tagged>, second: Tagged): [A, B]; + declare function inferNoInferOverloads(first: Tagged, B>, second: Tagged): [A, B]; + const noInferArguments = inferNoInferOverloads({ type: "a", value: 42 }, { type: "b", value: true }); + const noInferReversedArguments = inferNoInferOverloads({ type: "b", value: true }, { type: "a", value: 42 }); + + declare function inferReversedUnion(value: { type: "b"; value: B } | { type: "a"; value: A }): [A, B]; + const reversedTargetUnion = inferReversedUnion(taggedSource); + + declare function inferTwoDiscriminants(value: { type: "a"; sub: 1; value: A } | { type: "b"; sub: 2; value: B }): [A, B]; + const unmatchedTargetUnion = inferTwoDiscriminants({ type: "a", sub: 2, value: 42 }); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ type: "a"; sub: 2; value: number; }' is not assignable to parameter of type '{ type: "a"; sub: 1; value: number; } | { type: "b"; sub: 2; value: unknown; }'. +!!! error TS2345: Types of property 'sub' are incompatible. +!!! error TS2345: Type '2' is not assignable to type '1'. + const unmatchedTargetUnionReversedSource = inferTwoDiscriminants({ sub: 2, type: "a", value: 42 }); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ sub: 2; type: "a"; value: number; }' is not assignable to parameter of type '{ type: "a"; sub: 1; value: unknown; } | { type: "b"; sub: 2; value: number; }'. +!!! error TS2345: Types of property 'type' are incompatible. +!!! error TS2345: Type '"a"' is not assignable to type '"b"'. + + declare function inferTwoDiscriminantsReversed(value: { sub: 1; type: "a"; value: A } | { sub: 2; type: "b"; value: B }): [A, B]; + const unmatchedTargetUnionReversed = inferTwoDiscriminantsReversed({ type: "a", sub: 2, value: 42 }); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ type: "a"; sub: 2; value: number; }' is not assignable to parameter of type '{ sub: 1; type: "a"; value: number; } | { sub: 2; type: "b"; value: unknown; }'. +!!! error TS2345: Types of property 'sub' are incompatible. +!!! error TS2345: Type '2' is not assignable to type '1'. + + declare function inferOptionalUnion(value: { type?: "a"; value: A } | { type?: "b"; value: B }): [A, B]; + const optionalTargetUnion = inferOptionalUnion(optionalTag); + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=false).symbols b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=false).symbols new file mode 100644 index 0000000000000..303db88275506 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=false).symbols @@ -0,0 +1,758 @@ +//// [tests/cases/compiler/inferenceDiscriminatedUnions1.ts] //// + +=== inferenceDiscriminatedUnions1.ts === +type Ok = { ok: true; value: T }; +>Ok : Symbol(Ok, Decl(inferenceDiscriminatedUnions1.ts, 0, 0)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 0, 8)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 0, 14)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 0, 24)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 0, 8)) + +type Err = { ok: false; value: E }; +>Err : Symbol(Err, Decl(inferenceDiscriminatedUnions1.ts, 0, 36)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 1, 9)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 1, 15)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 1, 26)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 1, 9)) + +type ErrShape = { ok: false; value: string }; +>ErrShape : Symbol(ErrShape, Decl(inferenceDiscriminatedUnions1.ts, 1, 38)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 2, 17)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 2, 28)) + +type OkShape = { ok: true; value: string[] }; +>OkShape : Symbol(OkShape, Decl(inferenceDiscriminatedUnions1.ts, 2, 45)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 3, 16)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 3, 26)) + +enum K { A, B } +>K : Symbol(K, Decl(inferenceDiscriminatedUnions1.ts, 3, 45)) +>A : Symbol(K.A, Decl(inferenceDiscriminatedUnions1.ts, 4, 8)) +>B : Symbol(K.B, Decl(inferenceDiscriminatedUnions1.ts, 4, 11)) + +type Success = { kind: "success"; value: T }; +>Success : Symbol(Success, Decl(inferenceDiscriminatedUnions1.ts, 4, 15)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 5, 13)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 5, 19)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 5, 36)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 5, 13)) + +type Failure = { kind: "failure"; value: E }; +>Failure : Symbol(Failure, Decl(inferenceDiscriminatedUnions1.ts, 5, 48)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 6, 13)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 6, 19)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 6, 36)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 6, 13)) + +type Accepted = { kind: 1; value: T }; +>Accepted : Symbol(Accepted, Decl(inferenceDiscriminatedUnions1.ts, 6, 48)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 7, 14)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 7, 20)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 7, 29)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 7, 14)) + +type Rejected = { kind: 0; value: E }; +>Rejected : Symbol(Rejected, Decl(inferenceDiscriminatedUnions1.ts, 7, 41)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 8, 14)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 8, 20)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 8, 29)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 8, 14)) + +type OptionalOk = { ok?: true; value: T }; +>OptionalOk : Symbol(OptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 8, 41)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 9, 16)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 9, 22)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 9, 33)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 9, 16)) + +type MaybeErr = { ok?: false; value: E }; +>MaybeErr : Symbol(MaybeErr, Decl(inferenceDiscriminatedUnions1.ts, 9, 45)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 10, 14)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 10, 20)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 10, 32)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 10, 14)) + +type ExplicitOptionalOk = { ok?: true | undefined; value: T }; +>ExplicitOptionalOk : Symbol(ExplicitOptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 10, 44)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 11, 24)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 11, 30)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 11, 53)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 11, 24)) + +type UnionOk = { ok: true | undefined; value: T }; +>UnionOk : Symbol(UnionOk, Decl(inferenceDiscriminatedUnions1.ts, 11, 65)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 12, 13)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 12, 19)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 12, 41)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 12, 13)) + +type AlwaysUndefinedErr = { ok: undefined; value: E }; +>AlwaysUndefinedErr : Symbol(AlwaysUndefinedErr, Decl(inferenceDiscriminatedUnions1.ts, 12, 53)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 13, 24)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 13, 30)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 13, 45)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 13, 24)) + +type UndefinedOk = { ok: undefined; value: T }; +>UndefinedOk : Symbol(UndefinedOk, Decl(inferenceDiscriminatedUnions1.ts, 13, 57)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 14, 17)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 14, 23)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 14, 38)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 14, 17)) + +type Tagged = { type: "a"; value: A } | { type: "b"; value: B }; +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 15, 12)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 15, 14)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 15, 21)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 15, 32)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 15, 12)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 15, 47)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 15, 58)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 15, 14)) + +declare const u1: { kind: "b"; value: number } | { kind: "a"; value: string }; +>u1 : Symbol(u1, Decl(inferenceDiscriminatedUnions1.ts, 17, 13)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 17, 19)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 17, 30)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 17, 50)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 17, 61)) + +declare const u2: { kind: string; value: number } | { kind: "a"; value: string }; +>u2 : Symbol(u2, Decl(inferenceDiscriminatedUnions1.ts, 18, 13)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 18, 19)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 18, 33)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 18, 53)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 18, 64)) + +declare const broadTag: { kind: number; value: number } | { kind: "a"; value: string }; +>broadTag : Symbol(broadTag, Decl(inferenceDiscriminatedUnions1.ts, 19, 13)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 19, 25)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 19, 39)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 19, 59)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 19, 70)) + +declare const u3: { value: number } | { kind: "a"; value: string }; +>u3 : Symbol(u3, Decl(inferenceDiscriminatedUnions1.ts, 20, 13)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 20, 19)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 20, 39)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 20, 50)) + +declare const u4: { kind: "a"; sub: 2; value: string } | { kind: "b"; sub: 1; value: number }; +>u4 : Symbol(u4, Decl(inferenceDiscriminatedUnions1.ts, 21, 13)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 21, 19)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 21, 30)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 21, 38)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 21, 58)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 21, 69)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 21, 77)) + +declare const u5: { kind: K.B; value: number } | { kind: K.A; value: string }; +>u5 : Symbol(u5, Decl(inferenceDiscriminatedUnions1.ts, 22, 13)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 22, 19)) +>K : Symbol(K, Decl(inferenceDiscriminatedUnions1.ts, 3, 45)) +>B : Symbol(K.B, Decl(inferenceDiscriminatedUnions1.ts, 4, 11)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 22, 30)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 22, 50)) +>K : Symbol(K, Decl(inferenceDiscriminatedUnions1.ts, 3, 45)) +>A : Symbol(K.A, Decl(inferenceDiscriminatedUnions1.ts, 4, 8)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 22, 61)) + +declare const u6: Err | Ok; +>u6 : Symbol(u6, Decl(inferenceDiscriminatedUnions1.ts, 23, 13)) +>Err : Symbol(Err, Decl(inferenceDiscriminatedUnions1.ts, 0, 36)) +>Ok : Symbol(Ok, Decl(inferenceDiscriminatedUnions1.ts, 0, 0)) + +declare const taggedSource: Tagged; +>taggedSource : Symbol(taggedSource, Decl(inferenceDiscriminatedUnions1.ts, 24, 13)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) + +declare const reversedTaggedSource: { type: "b"; value: number } | { type: "a"; value: string }; +>reversedTaggedSource : Symbol(reversedTaggedSource, Decl(inferenceDiscriminatedUnions1.ts, 25, 13)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 25, 37)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 25, 48)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 25, 68)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 25, 79)) + +declare const broadSourceTag: { type: string; value: number }; +>broadSourceTag : Symbol(broadSourceTag, Decl(inferenceDiscriminatedUnions1.ts, 26, 13)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 26, 31)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 26, 45)) + +declare const missingTag: { value: number }; +>missingTag : Symbol(missingTag, Decl(inferenceDiscriminatedUnions1.ts, 27, 13)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 27, 27)) + +declare const optionalTag: { type?: "a"; value: string }; +>optionalTag : Symbol(optionalTag, Decl(inferenceDiscriminatedUnions1.ts, 28, 13)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 28, 28)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 28, 40)) + +declare function ok(value: T): Ok; +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 28, 57)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 30, 20)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 30, 29)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 30, 20)) +>Ok : Symbol(Ok, Decl(inferenceDiscriminatedUnions1.ts, 0, 0)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 30, 20)) + +export function aliasTarget(): ErrShape | OkShape { return ok([]); } +>aliasTarget : Symbol(aliasTarget, Decl(inferenceDiscriminatedUnions1.ts, 30, 46)) +>ErrShape : Symbol(ErrShape, Decl(inferenceDiscriminatedUnions1.ts, 1, 38)) +>OkShape : Symbol(OkShape, Decl(inferenceDiscriminatedUnions1.ts, 2, 45)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 28, 57)) + +export function f(): Ok | Err { +>f : Symbol(f, Decl(inferenceDiscriminatedUnions1.ts, 31, 68)) +>Ok : Symbol(Ok, Decl(inferenceDiscriminatedUnions1.ts, 0, 0)) +>Err : Symbol(Err, Decl(inferenceDiscriminatedUnions1.ts, 0, 36)) + + return ok([]); +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 28, 57)) +} + +export function optionalSource(): Ok | MaybeErr { +>optionalSource : Symbol(optionalSource, Decl(inferenceDiscriminatedUnions1.ts, 35, 1)) +>Ok : Symbol(Ok, Decl(inferenceDiscriminatedUnions1.ts, 0, 0)) +>MaybeErr : Symbol(MaybeErr, Decl(inferenceDiscriminatedUnions1.ts, 9, 45)) + + return ok([]); +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 28, 57)) +} + +declare function okInline(value: T): { ok: true; value: T }; +>okInline : Symbol(okInline, Decl(inferenceDiscriminatedUnions1.ts, 39, 1)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 41, 26)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 41, 35)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 41, 26)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 41, 47)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 41, 57)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 41, 26)) + +export function inlineTarget(): ErrShape | OkShape { return okInline([]); } +>inlineTarget : Symbol(inlineTarget, Decl(inferenceDiscriminatedUnions1.ts, 41, 69)) +>ErrShape : Symbol(ErrShape, Decl(inferenceDiscriminatedUnions1.ts, 1, 38)) +>OkShape : Symbol(OkShape, Decl(inferenceDiscriminatedUnions1.ts, 2, 45)) +>okInline : Symbol(okInline, Decl(inferenceDiscriminatedUnions1.ts, 39, 1)) + +export function inlineTargetReversed(): OkShape | ErrShape { return okInline([]); } +>inlineTargetReversed : Symbol(inlineTargetReversed, Decl(inferenceDiscriminatedUnions1.ts, 42, 75)) +>OkShape : Symbol(OkShape, Decl(inferenceDiscriminatedUnions1.ts, 2, 45)) +>ErrShape : Symbol(ErrShape, Decl(inferenceDiscriminatedUnions1.ts, 1, 38)) +>okInline : Symbol(okInline, Decl(inferenceDiscriminatedUnions1.ts, 39, 1)) + +declare function on(handler: (e: { kind: "a"; value: T }) => void): T; +>on : Symbol(on, Decl(inferenceDiscriminatedUnions1.ts, 44, 83)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 46, 20)) +>handler : Symbol(handler, Decl(inferenceDiscriminatedUnions1.ts, 46, 23)) +>e : Symbol(e, Decl(inferenceDiscriminatedUnions1.ts, 46, 33)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 46, 37)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 46, 48)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 46, 20)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 46, 20)) + +const r1 = on((e: { kind: "a"; value: string } | { kind: "b"; value: number }) => {}); +>r1 : Symbol(r1, Decl(inferenceDiscriminatedUnions1.ts, 47, 5)) +>on : Symbol(on, Decl(inferenceDiscriminatedUnions1.ts, 44, 83)) +>e : Symbol(e, Decl(inferenceDiscriminatedUnions1.ts, 47, 15)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 47, 19)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 47, 30)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 47, 50)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 47, 61)) + +const r2 = on((e: { kind: "b"; value: number } | { kind: "a"; value: string }) => {}); +>r2 : Symbol(r2, Decl(inferenceDiscriminatedUnions1.ts, 48, 5)) +>on : Symbol(on, Decl(inferenceDiscriminatedUnions1.ts, 44, 83)) +>e : Symbol(e, Decl(inferenceDiscriminatedUnions1.ts, 48, 15)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 48, 19)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 48, 30)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 48, 50)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 48, 61)) + +declare function pick(x: { kind: "a"; value: T }): T; +>pick : Symbol(pick, Decl(inferenceDiscriminatedUnions1.ts, 48, 86)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 50, 22)) +>x : Symbol(x, Decl(inferenceDiscriminatedUnions1.ts, 50, 25)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 50, 29)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 50, 40)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 50, 22)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 50, 22)) + +const r3 = pick(u1); +>r3 : Symbol(r3, Decl(inferenceDiscriminatedUnions1.ts, 51, 5)) +>pick : Symbol(pick, Decl(inferenceDiscriminatedUnions1.ts, 48, 86)) +>u1 : Symbol(u1, Decl(inferenceDiscriminatedUnions1.ts, 17, 13)) + +const r4 = pick(u2); +>r4 : Symbol(r4, Decl(inferenceDiscriminatedUnions1.ts, 52, 5)) +>pick : Symbol(pick, Decl(inferenceDiscriminatedUnions1.ts, 48, 86)) +>u2 : Symbol(u2, Decl(inferenceDiscriminatedUnions1.ts, 18, 13)) + +const broadResult = pick(broadTag); +>broadResult : Symbol(broadResult, Decl(inferenceDiscriminatedUnions1.ts, 53, 5)) +>pick : Symbol(pick, Decl(inferenceDiscriminatedUnions1.ts, 48, 86)) +>broadTag : Symbol(broadTag, Decl(inferenceDiscriminatedUnions1.ts, 19, 13)) + +const r5 = pick(u3); +>r5 : Symbol(r5, Decl(inferenceDiscriminatedUnions1.ts, 54, 5)) +>pick : Symbol(pick, Decl(inferenceDiscriminatedUnions1.ts, 48, 86)) +>u3 : Symbol(u3, Decl(inferenceDiscriminatedUnions1.ts, 20, 13)) + +declare function two(x: { kind: "a"; sub: 1; value: T }): T; +>two : Symbol(two, Decl(inferenceDiscriminatedUnions1.ts, 54, 20)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 56, 21)) +>x : Symbol(x, Decl(inferenceDiscriminatedUnions1.ts, 56, 24)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 56, 28)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 56, 39)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 56, 47)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 56, 21)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 56, 21)) + +const r6 = two(u4); +>r6 : Symbol(r6, Decl(inferenceDiscriminatedUnions1.ts, 57, 5)) +>two : Symbol(two, Decl(inferenceDiscriminatedUnions1.ts, 54, 20)) +>u4 : Symbol(u4, Decl(inferenceDiscriminatedUnions1.ts, 21, 13)) + +declare function twoReversed(x: { sub: 1; kind: "a"; value: T }): T; +>twoReversed : Symbol(twoReversed, Decl(inferenceDiscriminatedUnions1.ts, 57, 19)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 59, 29)) +>x : Symbol(x, Decl(inferenceDiscriminatedUnions1.ts, 59, 32)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 59, 36)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 59, 44)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 59, 55)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 59, 29)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 59, 29)) + +const r6Reversed = twoReversed(u4); +>r6Reversed : Symbol(r6Reversed, Decl(inferenceDiscriminatedUnions1.ts, 60, 5)) +>twoReversed : Symbol(twoReversed, Decl(inferenceDiscriminatedUnions1.ts, 57, 19)) +>u4 : Symbol(u4, Decl(inferenceDiscriminatedUnions1.ts, 21, 13)) + +declare function enumTag(x: { kind: K.A; value: T }): T; +>enumTag : Symbol(enumTag, Decl(inferenceDiscriminatedUnions1.ts, 60, 35)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 62, 25)) +>x : Symbol(x, Decl(inferenceDiscriminatedUnions1.ts, 62, 28)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 62, 32)) +>K : Symbol(K, Decl(inferenceDiscriminatedUnions1.ts, 3, 45)) +>A : Symbol(K.A, Decl(inferenceDiscriminatedUnions1.ts, 4, 8)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 62, 43)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 62, 25)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 62, 25)) + +const r7 = enumTag(u5); +>r7 : Symbol(r7, Decl(inferenceDiscriminatedUnions1.ts, 63, 5)) +>enumTag : Symbol(enumTag, Decl(inferenceDiscriminatedUnions1.ts, 60, 35)) +>u5 : Symbol(u5, Decl(inferenceDiscriminatedUnions1.ts, 22, 13)) + +declare function boolTag(x: { ok: boolean; value: T }): T; +>boolTag : Symbol(boolTag, Decl(inferenceDiscriminatedUnions1.ts, 63, 23)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 65, 25)) +>x : Symbol(x, Decl(inferenceDiscriminatedUnions1.ts, 65, 28)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 65, 32)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 65, 45)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 65, 25)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 65, 25)) + +const r8 = boolTag(u6); +>r8 : Symbol(r8, Decl(inferenceDiscriminatedUnions1.ts, 66, 5)) +>boolTag : Symbol(boolTag, Decl(inferenceDiscriminatedUnions1.ts, 63, 23)) +>u6 : Symbol(u6, Decl(inferenceDiscriminatedUnions1.ts, 23, 13)) + +declare function wrap(value: T): { result: Ok }; +>wrap : Symbol(wrap, Decl(inferenceDiscriminatedUnions1.ts, 66, 23)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 68, 22)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 68, 31)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 68, 22)) +>result : Symbol(result, Decl(inferenceDiscriminatedUnions1.ts, 68, 43)) +>Ok : Symbol(Ok, Decl(inferenceDiscriminatedUnions1.ts, 0, 0)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 68, 22)) + +export function nested(): { result: ErrShape | OkShape } { return wrap([]); } +>nested : Symbol(nested, Decl(inferenceDiscriminatedUnions1.ts, 68, 60)) +>result : Symbol(result, Decl(inferenceDiscriminatedUnions1.ts, 69, 27)) +>ErrShape : Symbol(ErrShape, Decl(inferenceDiscriminatedUnions1.ts, 1, 38)) +>OkShape : Symbol(OkShape, Decl(inferenceDiscriminatedUnions1.ts, 2, 45)) +>wrap : Symbol(wrap, Decl(inferenceDiscriminatedUnions1.ts, 66, 23)) + +declare function success(value: T): Success; +>success : Symbol(success, Decl(inferenceDiscriminatedUnions1.ts, 69, 77)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 71, 25)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 71, 34)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 71, 25)) +>Success : Symbol(Success, Decl(inferenceDiscriminatedUnions1.ts, 4, 15)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 71, 25)) + +export function withStringTag(): Success | Failure { +>withStringTag : Symbol(withStringTag, Decl(inferenceDiscriminatedUnions1.ts, 71, 56)) +>Success : Symbol(Success, Decl(inferenceDiscriminatedUnions1.ts, 4, 15)) +>Failure : Symbol(Failure, Decl(inferenceDiscriminatedUnions1.ts, 5, 48)) + + return success([]); +>success : Symbol(success, Decl(inferenceDiscriminatedUnions1.ts, 69, 77)) +} + +declare function accepted(value: T): Accepted; +>accepted : Symbol(accepted, Decl(inferenceDiscriminatedUnions1.ts, 74, 1)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 76, 26)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 76, 35)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 76, 26)) +>Accepted : Symbol(Accepted, Decl(inferenceDiscriminatedUnions1.ts, 6, 48)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 76, 26)) + +export function withNumberTag(): Accepted | Rejected { +>withNumberTag : Symbol(withNumberTag, Decl(inferenceDiscriminatedUnions1.ts, 76, 58)) +>Accepted : Symbol(Accepted, Decl(inferenceDiscriminatedUnions1.ts, 6, 48)) +>Rejected : Symbol(Rejected, Decl(inferenceDiscriminatedUnions1.ts, 7, 41)) + + return accepted([]); +>accepted : Symbol(accepted, Decl(inferenceDiscriminatedUnions1.ts, 74, 1)) +} + +declare function unmatched(): { kind: "other"; value: T }; +>unmatched : Symbol(unmatched, Decl(inferenceDiscriminatedUnions1.ts, 79, 1)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 81, 27)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 81, 34)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 81, 49)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 81, 27)) + +export function withUnmatchedTag(): Success | Failure { +>withUnmatchedTag : Symbol(withUnmatchedTag, Decl(inferenceDiscriminatedUnions1.ts, 81, 61)) +>Success : Symbol(Success, Decl(inferenceDiscriminatedUnions1.ts, 4, 15)) +>Failure : Symbol(Failure, Decl(inferenceDiscriminatedUnions1.ts, 5, 48)) + + return unmatched(); +>unmatched : Symbol(unmatched, Decl(inferenceDiscriminatedUnions1.ts, 79, 1)) +} + +declare function optionalOk(value: T): OptionalOk; +>optionalOk : Symbol(optionalOk, Decl(inferenceDiscriminatedUnions1.ts, 84, 1)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 86, 28)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 86, 37)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 86, 28)) +>OptionalOk : Symbol(OptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 8, 41)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 86, 28)) + +export function optionalTarget(): OptionalOk | Err { +>optionalTarget : Symbol(optionalTarget, Decl(inferenceDiscriminatedUnions1.ts, 86, 62)) +>OptionalOk : Symbol(OptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 8, 41)) +>Err : Symbol(Err, Decl(inferenceDiscriminatedUnions1.ts, 0, 36)) + + return optionalOk([]); +>optionalOk : Symbol(optionalOk, Decl(inferenceDiscriminatedUnions1.ts, 84, 1)) +} + +export function bothOptional(): OptionalOk | MaybeErr { +>bothOptional : Symbol(bothOptional, Decl(inferenceDiscriminatedUnions1.ts, 89, 1)) +>OptionalOk : Symbol(OptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 8, 41)) +>MaybeErr : Symbol(MaybeErr, Decl(inferenceDiscriminatedUnions1.ts, 9, 45)) + + return optionalOk([]); +>optionalOk : Symbol(optionalOk, Decl(inferenceDiscriminatedUnions1.ts, 84, 1)) +} + +export function missingSourceTag(): OptionalOk | { value: string } { +>missingSourceTag : Symbol(missingSourceTag, Decl(inferenceDiscriminatedUnions1.ts, 93, 1)) +>OptionalOk : Symbol(OptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 8, 41)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 95, 60)) + + return optionalOk([]); +>optionalOk : Symbol(optionalOk, Decl(inferenceDiscriminatedUnions1.ts, 84, 1)) +} + +export function undefinedSource(): OptionalOk | AlwaysUndefinedErr { +>undefinedSource : Symbol(undefinedSource, Decl(inferenceDiscriminatedUnions1.ts, 97, 1)) +>OptionalOk : Symbol(OptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 8, 41)) +>AlwaysUndefinedErr : Symbol(AlwaysUndefinedErr, Decl(inferenceDiscriminatedUnions1.ts, 12, 53)) + + return optionalOk([]); +>optionalOk : Symbol(optionalOk, Decl(inferenceDiscriminatedUnions1.ts, 84, 1)) +} + +declare function explicitOptionalOk(value: T): ExplicitOptionalOk; +>explicitOptionalOk : Symbol(explicitOptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 101, 1)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 103, 36)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 103, 45)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 103, 36)) +>ExplicitOptionalOk : Symbol(ExplicitOptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 10, 44)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 103, 36)) + +export function explicitUndefined(): ExplicitOptionalOk | Err { +>explicitUndefined : Symbol(explicitUndefined, Decl(inferenceDiscriminatedUnions1.ts, 103, 78)) +>ExplicitOptionalOk : Symbol(ExplicitOptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 10, 44)) +>Err : Symbol(Err, Decl(inferenceDiscriminatedUnions1.ts, 0, 36)) + + return explicitOptionalOk([]); +>explicitOptionalOk : Symbol(explicitOptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 101, 1)) +} + +export function explicitUndefinedOverlap(): ExplicitOptionalOk | AlwaysUndefinedErr { +>explicitUndefinedOverlap : Symbol(explicitUndefinedOverlap, Decl(inferenceDiscriminatedUnions1.ts, 106, 1)) +>ExplicitOptionalOk : Symbol(ExplicitOptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 10, 44)) +>AlwaysUndefinedErr : Symbol(AlwaysUndefinedErr, Decl(inferenceDiscriminatedUnions1.ts, 12, 53)) + + return explicitOptionalOk([]); +>explicitOptionalOk : Symbol(explicitOptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 101, 1)) +} + +declare function unionOk(value: T): UnionOk; +>unionOk : Symbol(unionOk, Decl(inferenceDiscriminatedUnions1.ts, 110, 1)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 112, 25)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 112, 34)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 112, 25)) +>UnionOk : Symbol(UnionOk, Decl(inferenceDiscriminatedUnions1.ts, 11, 65)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 112, 25)) + +export function requiredUnionTag(): UnionOk | Err { +>requiredUnionTag : Symbol(requiredUnionTag, Decl(inferenceDiscriminatedUnions1.ts, 112, 56)) +>UnionOk : Symbol(UnionOk, Decl(inferenceDiscriminatedUnions1.ts, 11, 65)) +>Err : Symbol(Err, Decl(inferenceDiscriminatedUnions1.ts, 0, 36)) + + return unionOk([]); +>unionOk : Symbol(unionOk, Decl(inferenceDiscriminatedUnions1.ts, 110, 1)) +} + +declare function undefinedOk(value: T): UndefinedOk; +>undefinedOk : Symbol(undefinedOk, Decl(inferenceDiscriminatedUnions1.ts, 115, 1)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 117, 29)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 117, 38)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 117, 29)) +>UndefinedOk : Symbol(UndefinedOk, Decl(inferenceDiscriminatedUnions1.ts, 13, 57)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 117, 29)) + +export function undefinedTarget(): UndefinedOk | MaybeErr { +>undefinedTarget : Symbol(undefinedTarget, Decl(inferenceDiscriminatedUnions1.ts, 117, 64)) +>UndefinedOk : Symbol(UndefinedOk, Decl(inferenceDiscriminatedUnions1.ts, 13, 57)) +>MaybeErr : Symbol(MaybeErr, Decl(inferenceDiscriminatedUnions1.ts, 9, 45)) + + return undefinedOk([]); +>undefinedOk : Symbol(undefinedOk, Decl(inferenceDiscriminatedUnions1.ts, 115, 1)) +} + +declare function inferTwoArguments(first: Tagged, second: Tagged): [A, B]; +>inferTwoArguments : Symbol(inferTwoArguments, Decl(inferenceDiscriminatedUnions1.ts, 120, 1)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 122, 35)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 122, 37)) +>first : Symbol(first, Decl(inferenceDiscriminatedUnions1.ts, 122, 41)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 122, 35)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 122, 37)) +>second : Symbol(second, Decl(inferenceDiscriminatedUnions1.ts, 122, 61)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 122, 35)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 122, 37)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 122, 35)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 122, 37)) + +const twoArguments = inferTwoArguments({ type: "a", value: 42 }, { type: "b", value: true }); +>twoArguments : Symbol(twoArguments, Decl(inferenceDiscriminatedUnions1.ts, 123, 5)) +>inferTwoArguments : Symbol(inferTwoArguments, Decl(inferenceDiscriminatedUnions1.ts, 120, 1)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 123, 40)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 123, 51)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 123, 66)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 123, 77)) + +declare function inferInlineUnion(value: { type: "a"; value: A } | { type: "b"; value: B }): [A, B]; +>inferInlineUnion : Symbol(inferInlineUnion, Decl(inferenceDiscriminatedUnions1.ts, 123, 93)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 125, 34)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 125, 36)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 125, 40)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 125, 48)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 125, 59)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 125, 34)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 125, 74)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 125, 85)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 125, 36)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 125, 34)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 125, 36)) + +const oneArgument = inferInlineUnion({ type: "a", value: 42 }); +>oneArgument : Symbol(oneArgument, Decl(inferenceDiscriminatedUnions1.ts, 126, 5)) +>inferInlineUnion : Symbol(inferInlineUnion, Decl(inferenceDiscriminatedUnions1.ts, 123, 93)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 126, 38)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 126, 49)) + +const unionArgument = inferInlineUnion(taggedSource); +>unionArgument : Symbol(unionArgument, Decl(inferenceDiscriminatedUnions1.ts, 127, 5)) +>inferInlineUnion : Symbol(inferInlineUnion, Decl(inferenceDiscriminatedUnions1.ts, 123, 93)) +>taggedSource : Symbol(taggedSource, Decl(inferenceDiscriminatedUnions1.ts, 24, 13)) + +const explicitUnionArgument = inferInlineUnion(taggedSource); +>explicitUnionArgument : Symbol(explicitUnionArgument, Decl(inferenceDiscriminatedUnions1.ts, 128, 5)) +>inferInlineUnion : Symbol(inferInlineUnion, Decl(inferenceDiscriminatedUnions1.ts, 123, 93)) +>taggedSource : Symbol(taggedSource, Decl(inferenceDiscriminatedUnions1.ts, 24, 13)) + +const reversedSourceUnion = inferInlineUnion(reversedTaggedSource); +>reversedSourceUnion : Symbol(reversedSourceUnion, Decl(inferenceDiscriminatedUnions1.ts, 129, 5)) +>inferInlineUnion : Symbol(inferInlineUnion, Decl(inferenceDiscriminatedUnions1.ts, 123, 93)) +>reversedTaggedSource : Symbol(reversedTaggedSource, Decl(inferenceDiscriminatedUnions1.ts, 25, 13)) + +const broadTargetUnion = inferInlineUnion(broadSourceTag); +>broadTargetUnion : Symbol(broadTargetUnion, Decl(inferenceDiscriminatedUnions1.ts, 130, 5)) +>inferInlineUnion : Symbol(inferInlineUnion, Decl(inferenceDiscriminatedUnions1.ts, 123, 93)) +>broadSourceTag : Symbol(broadSourceTag, Decl(inferenceDiscriminatedUnions1.ts, 26, 13)) + +const missingTargetUnion = inferInlineUnion(missingTag); +>missingTargetUnion : Symbol(missingTargetUnion, Decl(inferenceDiscriminatedUnions1.ts, 131, 5)) +>inferInlineUnion : Symbol(inferInlineUnion, Decl(inferenceDiscriminatedUnions1.ts, 123, 93)) +>missingTag : Symbol(missingTag, Decl(inferenceDiscriminatedUnions1.ts, 27, 13)) + +declare function inferUnionWithFallback(value: T | Tagged): [T, A, B]; +>inferUnionWithFallback : Symbol(inferUnionWithFallback, Decl(inferenceDiscriminatedUnions1.ts, 131, 56)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 133, 40)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 133, 51)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 133, 70)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 133, 73)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 133, 77)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 133, 40)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 133, 70)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 133, 73)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 133, 40)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 133, 70)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 133, 73)) + +const nakedTypeParameter = inferUnionWithFallback({ type: "a", value: 42 }); +>nakedTypeParameter : Symbol(nakedTypeParameter, Decl(inferenceDiscriminatedUnions1.ts, 134, 5)) +>inferUnionWithFallback : Symbol(inferUnionWithFallback, Decl(inferenceDiscriminatedUnions1.ts, 131, 56)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 134, 51)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 134, 62)) + +declare function inferNoInferOverloads(first: Tagged>, second: Tagged): [A, B]; +>inferNoInferOverloads : Symbol(inferNoInferOverloads, Decl(inferenceDiscriminatedUnions1.ts, 134, 76), Decl(inferenceDiscriminatedUnions1.ts, 136, 105)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 136, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 136, 41)) +>first : Symbol(first, Decl(inferenceDiscriminatedUnions1.ts, 136, 45)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 136, 39)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 136, 41)) +>second : Symbol(second, Decl(inferenceDiscriminatedUnions1.ts, 136, 74)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 136, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 136, 41)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 136, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 136, 41)) + +declare function inferNoInferOverloads(first: Tagged, B>, second: Tagged): [A, B]; +>inferNoInferOverloads : Symbol(inferNoInferOverloads, Decl(inferenceDiscriminatedUnions1.ts, 134, 76), Decl(inferenceDiscriminatedUnions1.ts, 136, 105)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 137, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 137, 41)) +>first : Symbol(first, Decl(inferenceDiscriminatedUnions1.ts, 137, 45)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 137, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 137, 41)) +>second : Symbol(second, Decl(inferenceDiscriminatedUnions1.ts, 137, 74)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 137, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 137, 41)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 137, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 137, 41)) + +const noInferArguments = inferNoInferOverloads({ type: "a", value: 42 }, { type: "b", value: true }); +>noInferArguments : Symbol(noInferArguments, Decl(inferenceDiscriminatedUnions1.ts, 138, 5)) +>inferNoInferOverloads : Symbol(inferNoInferOverloads, Decl(inferenceDiscriminatedUnions1.ts, 134, 76), Decl(inferenceDiscriminatedUnions1.ts, 136, 105)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 138, 48)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 138, 59)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 138, 74)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 138, 85)) + +const noInferReversedArguments = inferNoInferOverloads({ type: "b", value: true }, { type: "a", value: 42 }); +>noInferReversedArguments : Symbol(noInferReversedArguments, Decl(inferenceDiscriminatedUnions1.ts, 139, 5)) +>inferNoInferOverloads : Symbol(inferNoInferOverloads, Decl(inferenceDiscriminatedUnions1.ts, 134, 76), Decl(inferenceDiscriminatedUnions1.ts, 136, 105)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 139, 56)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 139, 67)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 139, 84)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 139, 95)) + +declare function inferReversedUnion(value: { type: "b"; value: B } | { type: "a"; value: A }): [A, B]; +>inferReversedUnion : Symbol(inferReversedUnion, Decl(inferenceDiscriminatedUnions1.ts, 139, 109)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 141, 36)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 141, 38)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 141, 42)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 141, 50)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 141, 61)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 141, 38)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 141, 76)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 141, 87)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 141, 36)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 141, 36)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 141, 38)) + +const reversedTargetUnion = inferReversedUnion(taggedSource); +>reversedTargetUnion : Symbol(reversedTargetUnion, Decl(inferenceDiscriminatedUnions1.ts, 142, 5)) +>inferReversedUnion : Symbol(inferReversedUnion, Decl(inferenceDiscriminatedUnions1.ts, 139, 109)) +>taggedSource : Symbol(taggedSource, Decl(inferenceDiscriminatedUnions1.ts, 24, 13)) + +declare function inferTwoDiscriminants(value: { type: "a"; sub: 1; value: A } | { type: "b"; sub: 2; value: B }): [A, B]; +>inferTwoDiscriminants : Symbol(inferTwoDiscriminants, Decl(inferenceDiscriminatedUnions1.ts, 142, 61)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 144, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 144, 41)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 144, 45)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 144, 53)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 144, 64)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 144, 72)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 144, 39)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 144, 87)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 144, 98)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 144, 106)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 144, 41)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 144, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 144, 41)) + +const unmatchedTargetUnion = inferTwoDiscriminants({ type: "a", sub: 2, value: 42 }); +>unmatchedTargetUnion : Symbol(unmatchedTargetUnion, Decl(inferenceDiscriminatedUnions1.ts, 145, 5)) +>inferTwoDiscriminants : Symbol(inferTwoDiscriminants, Decl(inferenceDiscriminatedUnions1.ts, 142, 61)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 145, 52)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 145, 63)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 145, 71)) + +const unmatchedTargetUnionReversedSource = inferTwoDiscriminants({ sub: 2, type: "a", value: 42 }); +>unmatchedTargetUnionReversedSource : Symbol(unmatchedTargetUnionReversedSource, Decl(inferenceDiscriminatedUnions1.ts, 146, 5)) +>inferTwoDiscriminants : Symbol(inferTwoDiscriminants, Decl(inferenceDiscriminatedUnions1.ts, 142, 61)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 146, 66)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 146, 74)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 146, 85)) + +declare function inferTwoDiscriminantsReversed(value: { sub: 1; type: "a"; value: A } | { sub: 2; type: "b"; value: B }): [A, B]; +>inferTwoDiscriminantsReversed : Symbol(inferTwoDiscriminantsReversed, Decl(inferenceDiscriminatedUnions1.ts, 146, 99)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 148, 47)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 148, 49)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 148, 53)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 148, 61)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 148, 69)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 148, 80)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 148, 47)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 148, 95)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 148, 103)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 148, 114)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 148, 49)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 148, 47)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 148, 49)) + +const unmatchedTargetUnionReversed = inferTwoDiscriminantsReversed({ type: "a", sub: 2, value: 42 }); +>unmatchedTargetUnionReversed : Symbol(unmatchedTargetUnionReversed, Decl(inferenceDiscriminatedUnions1.ts, 149, 5)) +>inferTwoDiscriminantsReversed : Symbol(inferTwoDiscriminantsReversed, Decl(inferenceDiscriminatedUnions1.ts, 146, 99)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 149, 68)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 149, 79)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 149, 87)) + +declare function inferOptionalUnion(value: { type?: "a"; value: A } | { type?: "b"; value: B }): [A, B]; +>inferOptionalUnion : Symbol(inferOptionalUnion, Decl(inferenceDiscriminatedUnions1.ts, 149, 101)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 151, 36)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 151, 38)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 151, 42)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 151, 50)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 151, 62)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 151, 36)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 151, 77)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 151, 89)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 151, 38)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 151, 36)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 151, 38)) + +const optionalTargetUnion = inferOptionalUnion(optionalTag); +>optionalTargetUnion : Symbol(optionalTargetUnion, Decl(inferenceDiscriminatedUnions1.ts, 152, 5)) +>inferOptionalUnion : Symbol(inferOptionalUnion, Decl(inferenceDiscriminatedUnions1.ts, 149, 101)) +>optionalTag : Symbol(optionalTag, Decl(inferenceDiscriminatedUnions1.ts, 28, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=false).types b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=false).types new file mode 100644 index 0000000000000..51233ebc8cdcc --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=false).types @@ -0,0 +1,669 @@ +//// [tests/cases/compiler/inferenceDiscriminatedUnions1.ts] //// + +=== inferenceDiscriminatedUnions1.ts === +type Ok = { ok: true; value: T }; +>Ok : Ok +>ok : true +>true : true +>value : T + +type Err = { ok: false; value: E }; +>Err : Err +>ok : false +>false : false +>value : E + +type ErrShape = { ok: false; value: string }; +>ErrShape : ErrShape +>ok : false +>false : false +>value : string + +type OkShape = { ok: true; value: string[] }; +>OkShape : OkShape +>ok : true +>true : true +>value : string[] + +enum K { A, B } +>K : K +>A : K.A +>B : K.B + +type Success = { kind: "success"; value: T }; +>Success : Success +>kind : "success" +>value : T + +type Failure = { kind: "failure"; value: E }; +>Failure : Failure +>kind : "failure" +>value : E + +type Accepted = { kind: 1; value: T }; +>Accepted : Accepted +>kind : 1 +>value : T + +type Rejected = { kind: 0; value: E }; +>Rejected : Rejected +>kind : 0 +>value : E + +type OptionalOk = { ok?: true; value: T }; +>OptionalOk : OptionalOk +>ok : true | undefined +>true : true +>value : T + +type MaybeErr = { ok?: false; value: E }; +>MaybeErr : MaybeErr +>ok : false | undefined +>false : false +>value : E + +type ExplicitOptionalOk = { ok?: true | undefined; value: T }; +>ExplicitOptionalOk : ExplicitOptionalOk +>ok : true | undefined +>true : true +>value : T + +type UnionOk = { ok: true | undefined; value: T }; +>UnionOk : UnionOk +>ok : true | undefined +>true : true +>value : T + +type AlwaysUndefinedErr = { ok: undefined; value: E }; +>AlwaysUndefinedErr : AlwaysUndefinedErr +>ok : undefined +>value : E + +type UndefinedOk = { ok: undefined; value: T }; +>UndefinedOk : UndefinedOk +>ok : undefined +>value : T + +type Tagged = { type: "a"; value: A } | { type: "b"; value: B }; +>Tagged : Tagged +>type : "a" +>value : A +>type : "b" +>value : B + +declare const u1: { kind: "b"; value: number } | { kind: "a"; value: string }; +>u1 : { kind: "b"; value: number; } | { kind: "a"; value: string; } +>kind : "b" +>value : number +>kind : "a" +>value : string + +declare const u2: { kind: string; value: number } | { kind: "a"; value: string }; +>u2 : { kind: string; value: number; } | { kind: "a"; value: string; } +>kind : string +>value : number +>kind : "a" +>value : string + +declare const broadTag: { kind: number; value: number } | { kind: "a"; value: string }; +>broadTag : { kind: number; value: number; } | { kind: "a"; value: string; } +>kind : number +>value : number +>kind : "a" +>value : string + +declare const u3: { value: number } | { kind: "a"; value: string }; +>u3 : { value: number; } | { kind: "a"; value: string; } +>value : number +>kind : "a" +>value : string + +declare const u4: { kind: "a"; sub: 2; value: string } | { kind: "b"; sub: 1; value: number }; +>u4 : { kind: "a"; sub: 2; value: string; } | { kind: "b"; sub: 1; value: number; } +>kind : "a" +>sub : 2 +>value : string +>kind : "b" +>sub : 1 +>value : number + +declare const u5: { kind: K.B; value: number } | { kind: K.A; value: string }; +>u5 : { kind: K.B; value: number; } | { kind: K.A; value: string; } +>kind : K.B +>K : any +>value : number +>kind : K.A +>K : any +>value : string + +declare const u6: Err | Ok; +>u6 : Err | Ok + +declare const taggedSource: Tagged; +>taggedSource : Tagged + +declare const reversedTaggedSource: { type: "b"; value: number } | { type: "a"; value: string }; +>reversedTaggedSource : { type: "b"; value: number; } | { type: "a"; value: string; } +>type : "b" +>value : number +>type : "a" +>value : string + +declare const broadSourceTag: { type: string; value: number }; +>broadSourceTag : { type: string; value: number; } +>type : string +>value : number + +declare const missingTag: { value: number }; +>missingTag : { value: number; } +>value : number + +declare const optionalTag: { type?: "a"; value: string }; +>optionalTag : { type?: "a"; value: string; } +>type : "a" | undefined +>value : string + +declare function ok(value: T): Ok; +>ok : (value: T) => Ok +>value : T + +export function aliasTarget(): ErrShape | OkShape { return ok([]); } +>aliasTarget : () => ErrShape | OkShape +>ok([]) : Ok<[]> +>ok : (value: T) => Ok +>[] : [] + +export function f(): Ok | Err { +>f : () => Ok | Err + + return ok([]); +>ok([]) : Ok<[]> +>ok : (value: T) => Ok +>[] : [] +} + +export function optionalSource(): Ok | MaybeErr { +>optionalSource : () => Ok | MaybeErr + + return ok([]); +>ok([]) : Ok<[]> +>ok : (value: T) => Ok +>[] : [] +} + +declare function okInline(value: T): { ok: true; value: T }; +>okInline : (value: T) => { ok: true; value: T; } +>value : T +>ok : true +>true : true +>value : T + +export function inlineTarget(): ErrShape | OkShape { return okInline([]); } +>inlineTarget : () => ErrShape | OkShape +>okInline([]) : { ok: true; value: []; } +>okInline : (value: T) => { ok: true; value: T; } +>[] : [] + +export function inlineTargetReversed(): OkShape | ErrShape { return okInline([]); } +>inlineTargetReversed : () => OkShape | ErrShape +>okInline([]) : { ok: true; value: []; } +>okInline : (value: T) => { ok: true; value: T; } +>[] : [] + +declare function on(handler: (e: { kind: "a"; value: T }) => void): T; +>on : (handler: (e: { kind: "a"; value: T; }) => void) => T +>handler : (e: { kind: "a"; value: T; }) => void +>e : { kind: "a"; value: T; } +>kind : "a" +>value : T + +const r1 = on((e: { kind: "a"; value: string } | { kind: "b"; value: number }) => {}); +>r1 : string +>on((e: { kind: "a"; value: string } | { kind: "b"; value: number }) => {}) : string +>on : (handler: (e: { kind: "a"; value: T; }) => void) => T +>(e: { kind: "a"; value: string } | { kind: "b"; value: number }) => {} : (e: { kind: "a"; value: string; } | { kind: "b"; value: number; }) => void +>e : { kind: "a"; value: string; } | { kind: "b"; value: number; } +>kind : "a" +>value : string +>kind : "b" +>value : number + +const r2 = on((e: { kind: "b"; value: number } | { kind: "a"; value: string }) => {}); +>r2 : string +>on((e: { kind: "b"; value: number } | { kind: "a"; value: string }) => {}) : string +>on : (handler: (e: { kind: "a"; value: T; }) => void) => T +>(e: { kind: "b"; value: number } | { kind: "a"; value: string }) => {} : (e: { kind: "b"; value: number; } | { kind: "a"; value: string; }) => void +>e : { kind: "b"; value: number; } | { kind: "a"; value: string; } +>kind : "b" +>value : number +>kind : "a" +>value : string + +declare function pick(x: { kind: "a"; value: T }): T; +>pick : (x: { kind: "a"; value: T; }) => T +>x : { kind: "a"; value: T; } +>kind : "a" +>value : T + +const r3 = pick(u1); +>r3 : string +>pick(u1) : string +>pick : (x: { kind: "a"; value: T; }) => T +>u1 : { kind: "b"; value: number; } | { kind: "a"; value: string; } + +const r4 = pick(u2); +>r4 : number +>pick(u2) : number +>pick : (x: { kind: "a"; value: T; }) => T +>u2 : { kind: string; value: number; } | { kind: "a"; value: string; } + +const broadResult = pick(broadTag); +>broadResult : string +>pick(broadTag) : string +>pick : (x: { kind: "a"; value: T; }) => T +>broadTag : { kind: number; value: number; } | { kind: "a"; value: string; } + +const r5 = pick(u3); +>r5 : number +>pick(u3) : number +>pick : (x: { kind: "a"; value: T; }) => T +>u3 : { value: number; } | { kind: "a"; value: string; } + +declare function two(x: { kind: "a"; sub: 1; value: T }): T; +>two : (x: { kind: "a"; sub: 1; value: T; }) => T +>x : { kind: "a"; sub: 1; value: T; } +>kind : "a" +>sub : 1 +>value : T + +const r6 = two(u4); +>r6 : string +>two(u4) : string +>two : (x: { kind: "a"; sub: 1; value: T; }) => T +>u4 : { kind: "a"; sub: 2; value: string; } | { kind: "b"; sub: 1; value: number; } + +declare function twoReversed(x: { sub: 1; kind: "a"; value: T }): T; +>twoReversed : (x: { sub: 1; kind: "a"; value: T; }) => T +>x : { sub: 1; kind: "a"; value: T; } +>sub : 1 +>kind : "a" +>value : T + +const r6Reversed = twoReversed(u4); +>r6Reversed : number +>twoReversed(u4) : number +>twoReversed : (x: { sub: 1; kind: "a"; value: T; }) => T +>u4 : { kind: "a"; sub: 2; value: string; } | { kind: "b"; sub: 1; value: number; } + +declare function enumTag(x: { kind: K.A; value: T }): T; +>enumTag : (x: { kind: K.A; value: T; }) => T +>x : { kind: K.A; value: T; } +>kind : K.A +>K : any +>value : T + +const r7 = enumTag(u5); +>r7 : string +>enumTag(u5) : string +>enumTag : (x: { kind: K.A; value: T; }) => T +>u5 : { kind: K.B; value: number; } | { kind: K.A; value: string; } + +declare function boolTag(x: { ok: boolean; value: T }): T; +>boolTag : (x: { ok: boolean; value: T; }) => T +>x : { ok: boolean; value: T; } +>ok : boolean +>value : T + +const r8 = boolTag(u6); +>r8 : number +>boolTag(u6) : number +>boolTag : (x: { ok: boolean; value: T; }) => T +>u6 : Err | Ok + +declare function wrap(value: T): { result: Ok }; +>wrap : (value: T) => { result: Ok; } +>value : T +>result : Ok + +export function nested(): { result: ErrShape | OkShape } { return wrap([]); } +>nested : () => { result: ErrShape | OkShape; } +>result : ErrShape | OkShape +>wrap([]) : { result: Ok<[]>; } +>wrap : (value: T) => { result: Ok; } +>[] : [] + +declare function success(value: T): Success; +>success : (value: T) => Success +>value : T + +export function withStringTag(): Success | Failure { +>withStringTag : () => Success | Failure + + return success([]); +>success([]) : Success<[]> +>success : (value: T) => Success +>[] : [] +} + +declare function accepted(value: T): Accepted; +>accepted : (value: T) => Accepted +>value : T + +export function withNumberTag(): Accepted | Rejected { +>withNumberTag : () => Accepted | Rejected + + return accepted([]); +>accepted([]) : Accepted<[]> +>accepted : (value: T) => Accepted +>[] : [] +} + +declare function unmatched(): { kind: "other"; value: T }; +>unmatched : () => { kind: "other"; value: T; } +>kind : "other" +>value : T + +export function withUnmatchedTag(): Success | Failure { +>withUnmatchedTag : () => Success | Failure + + return unmatched(); +>unmatched() : { kind: "other"; value: string[] | number[]; } +>unmatched : () => { kind: "other"; value: T; } +} + +declare function optionalOk(value: T): OptionalOk; +>optionalOk : (value: T) => OptionalOk +>value : T + +export function optionalTarget(): OptionalOk | Err { +>optionalTarget : () => OptionalOk | Err + + return optionalOk([]); +>optionalOk([]) : OptionalOk<[]> +>optionalOk : (value: T) => OptionalOk +>[] : [] +} + +export function bothOptional(): OptionalOk | MaybeErr { +>bothOptional : () => OptionalOk | MaybeErr + + return optionalOk([]); +>optionalOk([]) : OptionalOk +>optionalOk : (value: T) => OptionalOk +>[] : [] +} + +export function missingSourceTag(): OptionalOk | { value: string } { +>missingSourceTag : () => OptionalOk | { value: string; } +>value : string + + return optionalOk([]); +>optionalOk([]) : OptionalOk<[]> +>optionalOk : (value: T) => OptionalOk +>[] : [] +} + +export function undefinedSource(): OptionalOk | AlwaysUndefinedErr { +>undefinedSource : () => OptionalOk | AlwaysUndefinedErr + + return optionalOk([]); +>optionalOk([]) : OptionalOk +>optionalOk : (value: T) => OptionalOk +>[] : [] +} + +declare function explicitOptionalOk(value: T): ExplicitOptionalOk; +>explicitOptionalOk : (value: T) => ExplicitOptionalOk +>value : T + +export function explicitUndefined(): ExplicitOptionalOk | Err { +>explicitUndefined : () => ExplicitOptionalOk | Err + + return explicitOptionalOk([]); +>explicitOptionalOk([]) : ExplicitOptionalOk<[]> +>explicitOptionalOk : (value: T) => ExplicitOptionalOk +>[] : [] +} + +export function explicitUndefinedOverlap(): ExplicitOptionalOk | AlwaysUndefinedErr { +>explicitUndefinedOverlap : () => ExplicitOptionalOk | AlwaysUndefinedErr + + return explicitOptionalOk([]); +>explicitOptionalOk([]) : ExplicitOptionalOk +>explicitOptionalOk : (value: T) => ExplicitOptionalOk +>[] : [] +} + +declare function unionOk(value: T): UnionOk; +>unionOk : (value: T) => UnionOk +>value : T + +export function requiredUnionTag(): UnionOk | Err { +>requiredUnionTag : () => UnionOk | Err + + return unionOk([]); +>unionOk([]) : UnionOk<[]> +>unionOk : (value: T) => UnionOk +>[] : [] +} + +declare function undefinedOk(value: T): UndefinedOk; +>undefinedOk : (value: T) => UndefinedOk +>value : T + +export function undefinedTarget(): UndefinedOk | MaybeErr { +>undefinedTarget : () => UndefinedOk | MaybeErr + + return undefinedOk([]); +>undefinedOk([]) : UndefinedOk +>undefinedOk : (value: T) => UndefinedOk +>[] : [] +} + +declare function inferTwoArguments(first: Tagged, second: Tagged): [A, B]; +>inferTwoArguments : (first: Tagged, second: Tagged) => [A, B] +>first : Tagged +>second : Tagged + +const twoArguments = inferTwoArguments({ type: "a", value: 42 }, { type: "b", value: true }); +>twoArguments : [number, boolean] +>inferTwoArguments({ type: "a", value: 42 }, { type: "b", value: true }) : [number, boolean] +>inferTwoArguments : (first: Tagged, second: Tagged) => [A, B] +>{ type: "a", value: 42 } : { type: "a"; value: number; } +>type : "a" +>"a" : "a" +>value : number +>42 : 42 +>{ type: "b", value: true } : { type: "b"; value: true; } +>type : "b" +>"b" : "b" +>value : true +>true : true + +declare function inferInlineUnion(value: { type: "a"; value: A } | { type: "b"; value: B }): [A, B]; +>inferInlineUnion : (value: { type: "a"; value: A; } | { type: "b"; value: B; }) => [A, B] +>value : { type: "a"; value: A; } | { type: "b"; value: B; } +>type : "a" +>value : A +>type : "b" +>value : B + +const oneArgument = inferInlineUnion({ type: "a", value: 42 }); +>oneArgument : [number, unknown] +>inferInlineUnion({ type: "a", value: 42 }) : [number, unknown] +>inferInlineUnion : (value: { type: "a"; value: A; } | { type: "b"; value: B; }) => [A, B] +>{ type: "a", value: 42 } : { type: "a"; value: number; } +>type : "a" +>"a" : "a" +>value : number +>42 : 42 + +const unionArgument = inferInlineUnion(taggedSource); +>unionArgument : [string, number] +>inferInlineUnion(taggedSource) : [string, number] +>inferInlineUnion : (value: { type: "a"; value: A; } | { type: "b"; value: B; }) => [A, B] +>taggedSource : Tagged + +const explicitUnionArgument = inferInlineUnion(taggedSource); +>explicitUnionArgument : [string, number] +>inferInlineUnion(taggedSource) : [string, number] +>inferInlineUnion : (value: { type: "a"; value: A; } | { type: "b"; value: B; }) => [A, B] +>taggedSource : Tagged + +const reversedSourceUnion = inferInlineUnion(reversedTaggedSource); +>reversedSourceUnion : [string, number] +>inferInlineUnion(reversedTaggedSource) : [string, number] +>inferInlineUnion : (value: { type: "a"; value: A; } | { type: "b"; value: B; }) => [A, B] +>reversedTaggedSource : { type: "b"; value: number; } | { type: "a"; value: string; } + +const broadTargetUnion = inferInlineUnion(broadSourceTag); +>broadTargetUnion : [number, number] +>inferInlineUnion(broadSourceTag) : [number, number] +>inferInlineUnion : (value: { type: "a"; value: A; } | { type: "b"; value: B; }) => [A, B] +>broadSourceTag : { type: string; value: number; } + +const missingTargetUnion = inferInlineUnion(missingTag); +>missingTargetUnion : [number, number] +>inferInlineUnion(missingTag) : [number, number] +>inferInlineUnion : (value: { type: "a"; value: A; } | { type: "b"; value: B; }) => [A, B] +>missingTag : { value: number; } + +declare function inferUnionWithFallback(value: T | Tagged): [T, A, B]; +>inferUnionWithFallback : (value: T | Tagged) => [T, A, B] +>type : "a" | "b" +>value : T | Tagged + +const nakedTypeParameter = inferUnionWithFallback({ type: "a", value: 42 }); +>nakedTypeParameter : [{ type: "a"; value: number; }, number, unknown] +>inferUnionWithFallback({ type: "a", value: 42 }) : [{ type: "a"; value: number; }, number, unknown] +>inferUnionWithFallback : (value: T | Tagged) => [T, A, B] +>{ type: "a", value: 42 } : { type: "a"; value: number; } +>type : "a" +>"a" : "a" +>value : number +>42 : 42 + +declare function inferNoInferOverloads(first: Tagged>, second: Tagged): [A, B]; +>inferNoInferOverloads : { (first: Tagged>, second: Tagged): [A, B]; (first: Tagged, B_1>, second: Tagged): [A_1, B_1]; } +>first : Tagged> +>second : Tagged + +declare function inferNoInferOverloads(first: Tagged, B>, second: Tagged): [A, B]; +>inferNoInferOverloads : { (first: Tagged>, second: Tagged): [A_1, B_1]; (first: Tagged, B>, second: Tagged): [A, B]; } +>first : Tagged, B> +>second : Tagged + +const noInferArguments = inferNoInferOverloads({ type: "a", value: 42 }, { type: "b", value: true }); +>noInferArguments : [number, boolean] +>inferNoInferOverloads({ type: "a", value: 42 }, { type: "b", value: true }) : [number, boolean] +>inferNoInferOverloads : { (first: Tagged>, second: Tagged): [A, B]; (first: Tagged, B>, second: Tagged): [A, B]; } +>{ type: "a", value: 42 } : { type: "a"; value: number; } +>type : "a" +>"a" : "a" +>value : number +>42 : 42 +>{ type: "b", value: true } : { type: "b"; value: true; } +>type : "b" +>"b" : "b" +>value : true +>true : true + +const noInferReversedArguments = inferNoInferOverloads({ type: "b", value: true }, { type: "a", value: 42 }); +>noInferReversedArguments : [number, unknown] +>inferNoInferOverloads({ type: "b", value: true }, { type: "a", value: 42 }) : [number, unknown] +>inferNoInferOverloads : { (first: Tagged>, second: Tagged): [A, B]; (first: Tagged, B>, second: Tagged): [A, B]; } +>{ type: "b", value: true } : { type: "b"; value: boolean; } +>type : "b" +>"b" : "b" +>value : boolean +>true : true +>{ type: "a", value: 42 } : { type: "a"; value: number; } +>type : "a" +>"a" : "a" +>value : number +>42 : 42 + +declare function inferReversedUnion(value: { type: "b"; value: B } | { type: "a"; value: A }): [A, B]; +>inferReversedUnion : (value: { type: "b"; value: B; } | { type: "a"; value: A; }) => [A, B] +>value : { type: "b"; value: B; } | { type: "a"; value: A; } +>type : "b" +>value : B +>type : "a" +>value : A + +const reversedTargetUnion = inferReversedUnion(taggedSource); +>reversedTargetUnion : [string, number] +>inferReversedUnion(taggedSource) : [string, number] +>inferReversedUnion : (value: { type: "b"; value: B; } | { type: "a"; value: A; }) => [A, B] +>taggedSource : Tagged + +declare function inferTwoDiscriminants(value: { type: "a"; sub: 1; value: A } | { type: "b"; sub: 2; value: B }): [A, B]; +>inferTwoDiscriminants : (value: { type: "a"; sub: 1; value: A; } | { type: "b"; sub: 2; value: B; }) => [A, B] +>value : { type: "a"; sub: 1; value: A; } | { type: "b"; sub: 2; value: B; } +>type : "a" +>sub : 1 +>value : A +>type : "b" +>sub : 2 +>value : B + +const unmatchedTargetUnion = inferTwoDiscriminants({ type: "a", sub: 2, value: 42 }); +>unmatchedTargetUnion : [number, unknown] +>inferTwoDiscriminants({ type: "a", sub: 2, value: 42 }) : [number, unknown] +>inferTwoDiscriminants : (value: { type: "a"; sub: 1; value: A; } | { type: "b"; sub: 2; value: B; }) => [A, B] +>{ type: "a", sub: 2, value: 42 } : { type: "a"; sub: 2; value: number; } +>type : "a" +>"a" : "a" +>sub : 2 +>2 : 2 +>value : number +>42 : 42 + +const unmatchedTargetUnionReversedSource = inferTwoDiscriminants({ sub: 2, type: "a", value: 42 }); +>unmatchedTargetUnionReversedSource : [unknown, number] +>inferTwoDiscriminants({ sub: 2, type: "a", value: 42 }) : [unknown, number] +>inferTwoDiscriminants : (value: { type: "a"; sub: 1; value: A; } | { type: "b"; sub: 2; value: B; }) => [A, B] +>{ sub: 2, type: "a", value: 42 } : { sub: 2; type: "a"; value: number; } +>sub : 2 +>2 : 2 +>type : "a" +>"a" : "a" +>value : number +>42 : 42 + +declare function inferTwoDiscriminantsReversed(value: { sub: 1; type: "a"; value: A } | { sub: 2; type: "b"; value: B }): [A, B]; +>inferTwoDiscriminantsReversed : (value: { sub: 1; type: "a"; value: A; } | { sub: 2; type: "b"; value: B; }) => [A, B] +>value : { sub: 1; type: "a"; value: A; } | { sub: 2; type: "b"; value: B; } +>sub : 1 +>type : "a" +>value : A +>sub : 2 +>type : "b" +>value : B + +const unmatchedTargetUnionReversed = inferTwoDiscriminantsReversed({ type: "a", sub: 2, value: 42 }); +>unmatchedTargetUnionReversed : [number, unknown] +>inferTwoDiscriminantsReversed({ type: "a", sub: 2, value: 42 }) : [number, unknown] +>inferTwoDiscriminantsReversed : (value: { sub: 1; type: "a"; value: A; } | { sub: 2; type: "b"; value: B; }) => [A, B] +>{ type: "a", sub: 2, value: 42 } : { type: "a"; sub: 2; value: number; } +>type : "a" +>"a" : "a" +>sub : 2 +>2 : 2 +>value : number +>42 : 42 + +declare function inferOptionalUnion(value: { type?: "a"; value: A } | { type?: "b"; value: B }): [A, B]; +>inferOptionalUnion : (value: { type?: "a"; value: A; } | { type?: "b"; value: B; }) => [A, B] +>value : { type?: "a"; value: A; } | { type?: "b"; value: B; } +>type : "a" | undefined +>value : A +>type : "b" | undefined +>value : B + +const optionalTargetUnion = inferOptionalUnion(optionalTag); +>optionalTargetUnion : [string, string] +>inferOptionalUnion(optionalTag) : [string, string] +>inferOptionalUnion : (value: { type?: "a"; value: A; } | { type?: "b"; value: B; }) => [A, B] +>optionalTag : { type?: "a"; value: string; } + diff --git a/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=true).errors.txt b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=true).errors.txt new file mode 100644 index 0000000000000..f414a562f6319 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=true).errors.txt @@ -0,0 +1,299 @@ +inferenceDiscriminatedUnions1.ts(52,17): error TS2345: Argument of type '{ kind: "b"; value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: string; }'. + Type '{ kind: "b"; value: number; }' is not assignable to type '{ kind: "a"; value: string; }'. + Types of property 'kind' are incompatible. + Type '"b"' is not assignable to type '"a"'. +inferenceDiscriminatedUnions1.ts(53,17): error TS2345: Argument of type '{ kind: string; value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: number; }'. + Type '{ kind: string; value: number; }' is not assignable to type '{ kind: "a"; value: number; }'. + Types of property 'kind' are incompatible. + Type 'string' is not assignable to type '"a"'. +inferenceDiscriminatedUnions1.ts(54,26): error TS2345: Argument of type '{ kind: number; value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: string; }'. + Type '{ kind: number; value: number; }' is not assignable to type '{ kind: "a"; value: string; }'. + Types of property 'kind' are incompatible. + Type 'number' is not assignable to type '"a"'. +inferenceDiscriminatedUnions1.ts(55,17): error TS2345: Argument of type '{ value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: number; }'. + Property 'kind' is missing in type '{ value: number; }' but required in type '{ kind: "a"; value: number; }'. +inferenceDiscriminatedUnions1.ts(58,16): error TS2345: Argument of type '{ kind: "a"; sub: 2; value: string; } | { kind: "b"; sub: 1; value: number; }' is not assignable to parameter of type '{ kind: "a"; sub: 1; value: string; }'. + Type '{ kind: "a"; sub: 2; value: string; }' is not assignable to type '{ kind: "a"; sub: 1; value: string; }'. + Types of property 'sub' are incompatible. + Type '2' is not assignable to type '1'. +inferenceDiscriminatedUnions1.ts(61,32): error TS2345: Argument of type '{ kind: "a"; sub: 2; value: string; } | { kind: "b"; sub: 1; value: number; }' is not assignable to parameter of type '{ sub: 1; kind: "a"; value: number; }'. + Type '{ kind: "a"; sub: 2; value: string; }' is not assignable to type '{ sub: 1; kind: "a"; value: number; }'. + Types of property 'sub' are incompatible. + Type '2' is not assignable to type '1'. +inferenceDiscriminatedUnions1.ts(64,20): error TS2345: Argument of type '{ kind: K.B; value: number; } | { kind: K.A; value: string; }' is not assignable to parameter of type '{ kind: K.A; value: string; }'. + Type '{ kind: K.B; value: number; }' is not assignable to type '{ kind: K.A; value: string; }'. + Types of property 'kind' are incompatible. + Type 'K.B' is not assignable to type 'K.A'. +inferenceDiscriminatedUnions1.ts(67,20): error TS2345: Argument of type 'Err | Ok' is not assignable to parameter of type '{ ok: boolean; value: number; }'. + Type 'Ok' is not assignable to type '{ ok: boolean; value: number; }'. + Types of property 'value' are incompatible. + Type 'string' is not assignable to type 'number'. +inferenceDiscriminatedUnions1.ts(84,5): error TS2322: Type '{ kind: "other"; value: string[] | number[]; }' is not assignable to type 'Failure | Success'. + Type '{ kind: "other"; value: string[] | number[]; }' is not assignable to type 'Success'. + Types of property 'kind' are incompatible. + Type '"other"' is not assignable to type '"success"'. +inferenceDiscriminatedUnions1.ts(93,5): error TS2375: Type 'OptionalOk' is not assignable to type 'MaybeErr | OptionalOk' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Type 'OptionalOk' is not assignable to type 'OptionalOk' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. +inferenceDiscriminatedUnions1.ts(101,5): error TS2322: Type 'OptionalOk' is not assignable to type 'AlwaysUndefinedErr | OptionalOk'. + Type 'OptionalOk' is not assignable to type 'OptionalOk' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. +inferenceDiscriminatedUnions1.ts(110,5): error TS2322: Type 'ExplicitOptionalOk' is not assignable to type 'AlwaysUndefinedErr | ExplicitOptionalOk'. + Type 'ExplicitOptionalOk' is not assignable to type 'ExplicitOptionalOk'. + The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. +inferenceDiscriminatedUnions1.ts(120,5): error TS2322: Type 'UndefinedOk' is not assignable to type 'MaybeErr | UndefinedOk'. + Type 'UndefinedOk' is not assignable to type 'UndefinedOk'. + The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. +inferenceDiscriminatedUnions1.ts(131,43): error TS2345: Argument of type '{ type: string; value: number; }' is not assignable to parameter of type '{ type: "a"; value: number; } | { type: "b"; value: number; }'. + Type '{ type: string; value: number; }' is not assignable to type '{ type: "b"; value: number; }'. + Types of property 'type' are incompatible. + Type 'string' is not assignable to type '"b"'. +inferenceDiscriminatedUnions1.ts(132,45): error TS2345: Argument of type '{ value: number; }' is not assignable to parameter of type '{ type: "a"; value: number; } | { type: "b"; value: number; }'. + Property 'type' is missing in type '{ value: number; }' but required in type '{ type: "b"; value: number; }'. +inferenceDiscriminatedUnions1.ts(146,52): error TS2345: Argument of type '{ type: "a"; sub: 2; value: number; }' is not assignable to parameter of type '{ type: "a"; sub: 1; value: number; } | { type: "b"; sub: 2; value: unknown; }'. + Types of property 'sub' are incompatible. + Type '2' is not assignable to type '1'. +inferenceDiscriminatedUnions1.ts(147,66): error TS2345: Argument of type '{ sub: 2; type: "a"; value: number; }' is not assignable to parameter of type '{ type: "a"; sub: 1; value: unknown; } | { type: "b"; sub: 2; value: number; }'. + Types of property 'type' are incompatible. + Type '"a"' is not assignable to type '"b"'. +inferenceDiscriminatedUnions1.ts(150,68): error TS2345: Argument of type '{ type: "a"; sub: 2; value: number; }' is not assignable to parameter of type '{ sub: 1; type: "a"; value: number; } | { sub: 2; type: "b"; value: unknown; }'. + Types of property 'sub' are incompatible. + Type '2' is not assignable to type '1'. + + +==== inferenceDiscriminatedUnions1.ts (18 errors) ==== + type Ok = { ok: true; value: T }; + type Err = { ok: false; value: E }; + type ErrShape = { ok: false; value: string }; + type OkShape = { ok: true; value: string[] }; + enum K { A, B } + type Success = { kind: "success"; value: T }; + type Failure = { kind: "failure"; value: E }; + type Accepted = { kind: 1; value: T }; + type Rejected = { kind: 0; value: E }; + type OptionalOk = { ok?: true; value: T }; + type MaybeErr = { ok?: false; value: E }; + type ExplicitOptionalOk = { ok?: true | undefined; value: T }; + type UnionOk = { ok: true | undefined; value: T }; + type AlwaysUndefinedErr = { ok: undefined; value: E }; + type UndefinedOk = { ok: undefined; value: T }; + type Tagged = { type: "a"; value: A } | { type: "b"; value: B }; + + declare const u1: { kind: "b"; value: number } | { kind: "a"; value: string }; + declare const u2: { kind: string; value: number } | { kind: "a"; value: string }; + declare const broadTag: { kind: number; value: number } | { kind: "a"; value: string }; + declare const u3: { value: number } | { kind: "a"; value: string }; + declare const u4: { kind: "a"; sub: 2; value: string } | { kind: "b"; sub: 1; value: number }; + declare const u5: { kind: K.B; value: number } | { kind: K.A; value: string }; + declare const u6: Err | Ok; + declare const taggedSource: Tagged; + declare const reversedTaggedSource: { type: "b"; value: number } | { type: "a"; value: string }; + declare const broadSourceTag: { type: string; value: number }; + declare const missingTag: { value: number }; + declare const optionalTag: { type?: "a"; value: string }; + + declare function ok(value: T): Ok; + export function aliasTarget(): ErrShape | OkShape { return ok([]); } + + export function f(): Ok | Err { + return ok([]); + } + + export function optionalSource(): Ok | MaybeErr { + return ok([]); + } + + declare function okInline(value: T): { ok: true; value: T }; + export function inlineTarget(): ErrShape | OkShape { return okInline([]); } + + export function inlineTargetReversed(): OkShape | ErrShape { return okInline([]); } + + declare function on(handler: (e: { kind: "a"; value: T }) => void): T; + const r1 = on((e: { kind: "a"; value: string } | { kind: "b"; value: number }) => {}); + const r2 = on((e: { kind: "b"; value: number } | { kind: "a"; value: string }) => {}); + + declare function pick(x: { kind: "a"; value: T }): T; + const r3 = pick(u1); + ~~ +!!! error TS2345: Argument of type '{ kind: "b"; value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: string; }'. +!!! error TS2345: Type '{ kind: "b"; value: number; }' is not assignable to type '{ kind: "a"; value: string; }'. +!!! error TS2345: Types of property 'kind' are incompatible. +!!! error TS2345: Type '"b"' is not assignable to type '"a"'. + const r4 = pick(u2); + ~~ +!!! error TS2345: Argument of type '{ kind: string; value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: number; }'. +!!! error TS2345: Type '{ kind: string; value: number; }' is not assignable to type '{ kind: "a"; value: number; }'. +!!! error TS2345: Types of property 'kind' are incompatible. +!!! error TS2345: Type 'string' is not assignable to type '"a"'. + const broadResult = pick(broadTag); + ~~~~~~~~ +!!! error TS2345: Argument of type '{ kind: number; value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: string; }'. +!!! error TS2345: Type '{ kind: number; value: number; }' is not assignable to type '{ kind: "a"; value: string; }'. +!!! error TS2345: Types of property 'kind' are incompatible. +!!! error TS2345: Type 'number' is not assignable to type '"a"'. + const r5 = pick(u3); + ~~ +!!! error TS2345: Argument of type '{ value: number; } | { kind: "a"; value: string; }' is not assignable to parameter of type '{ kind: "a"; value: number; }'. +!!! error TS2345: Property 'kind' is missing in type '{ value: number; }' but required in type '{ kind: "a"; value: number; }'. +!!! related TS2728 inferenceDiscriminatedUnions1.ts:51:31: 'kind' is declared here. + + declare function two(x: { kind: "a"; sub: 1; value: T }): T; + const r6 = two(u4); + ~~ +!!! error TS2345: Argument of type '{ kind: "a"; sub: 2; value: string; } | { kind: "b"; sub: 1; value: number; }' is not assignable to parameter of type '{ kind: "a"; sub: 1; value: string; }'. +!!! error TS2345: Type '{ kind: "a"; sub: 2; value: string; }' is not assignable to type '{ kind: "a"; sub: 1; value: string; }'. +!!! error TS2345: Types of property 'sub' are incompatible. +!!! error TS2345: Type '2' is not assignable to type '1'. + + declare function twoReversed(x: { sub: 1; kind: "a"; value: T }): T; + const r6Reversed = twoReversed(u4); + ~~ +!!! error TS2345: Argument of type '{ kind: "a"; sub: 2; value: string; } | { kind: "b"; sub: 1; value: number; }' is not assignable to parameter of type '{ sub: 1; kind: "a"; value: number; }'. +!!! error TS2345: Type '{ kind: "a"; sub: 2; value: string; }' is not assignable to type '{ sub: 1; kind: "a"; value: number; }'. +!!! error TS2345: Types of property 'sub' are incompatible. +!!! error TS2345: Type '2' is not assignable to type '1'. + + declare function enumTag(x: { kind: K.A; value: T }): T; + const r7 = enumTag(u5); + ~~ +!!! error TS2345: Argument of type '{ kind: K.B; value: number; } | { kind: K.A; value: string; }' is not assignable to parameter of type '{ kind: K.A; value: string; }'. +!!! error TS2345: Type '{ kind: K.B; value: number; }' is not assignable to type '{ kind: K.A; value: string; }'. +!!! error TS2345: Types of property 'kind' are incompatible. +!!! error TS2345: Type 'K.B' is not assignable to type 'K.A'. + + declare function boolTag(x: { ok: boolean; value: T }): T; + const r8 = boolTag(u6); + ~~ +!!! error TS2345: Argument of type 'Err | Ok' is not assignable to parameter of type '{ ok: boolean; value: number; }'. +!!! error TS2345: Type 'Ok' is not assignable to type '{ ok: boolean; value: number; }'. +!!! error TS2345: Types of property 'value' are incompatible. +!!! error TS2345: Type 'string' is not assignable to type 'number'. + + declare function wrap(value: T): { result: Ok }; + export function nested(): { result: ErrShape | OkShape } { return wrap([]); } + + declare function success(value: T): Success; + export function withStringTag(): Success | Failure { + return success([]); + } + + declare function accepted(value: T): Accepted; + export function withNumberTag(): Accepted | Rejected { + return accepted([]); + } + + declare function unmatched(): { kind: "other"; value: T }; + export function withUnmatchedTag(): Success | Failure { + return unmatched(); + ~~~~~~ +!!! error TS2322: Type '{ kind: "other"; value: string[] | number[]; }' is not assignable to type 'Failure | Success'. +!!! error TS2322: Type '{ kind: "other"; value: string[] | number[]; }' is not assignable to type 'Success'. +!!! error TS2322: Types of property 'kind' are incompatible. +!!! error TS2322: Type '"other"' is not assignable to type '"success"'. + } + + declare function optionalOk(value: T): OptionalOk; + export function optionalTarget(): OptionalOk | Err { + return optionalOk([]); + } + + export function bothOptional(): OptionalOk | MaybeErr { + return optionalOk([]); + ~~~~~~ +!!! error TS2375: Type 'OptionalOk' is not assignable to type 'MaybeErr | OptionalOk' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2375: Type 'OptionalOk' is not assignable to type 'OptionalOk' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2375: The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. + } + + export function missingSourceTag(): OptionalOk | { value: string } { + return optionalOk([]); + } + + export function undefinedSource(): OptionalOk | AlwaysUndefinedErr { + return optionalOk([]); + ~~~~~~ +!!! error TS2322: Type 'OptionalOk' is not assignable to type 'AlwaysUndefinedErr | OptionalOk'. +!!! error TS2322: Type 'OptionalOk' is not assignable to type 'OptionalOk' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2322: The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. + } + + declare function explicitOptionalOk(value: T): ExplicitOptionalOk; + export function explicitUndefined(): ExplicitOptionalOk | Err { + return explicitOptionalOk([]); + } + + export function explicitUndefinedOverlap(): ExplicitOptionalOk | AlwaysUndefinedErr { + return explicitOptionalOk([]); + ~~~~~~ +!!! error TS2322: Type 'ExplicitOptionalOk' is not assignable to type 'AlwaysUndefinedErr | ExplicitOptionalOk'. +!!! error TS2322: Type 'ExplicitOptionalOk' is not assignable to type 'ExplicitOptionalOk'. +!!! error TS2322: The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. + } + + declare function unionOk(value: T): UnionOk; + export function requiredUnionTag(): UnionOk | Err { + return unionOk([]); + } + + declare function undefinedOk(value: T): UndefinedOk; + export function undefinedTarget(): UndefinedOk | MaybeErr { + return undefinedOk([]); + ~~~~~~ +!!! error TS2322: Type 'UndefinedOk' is not assignable to type 'MaybeErr | UndefinedOk'. +!!! error TS2322: Type 'UndefinedOk' is not assignable to type 'UndefinedOk'. +!!! error TS2322: The type 'readonly []' is 'readonly' and cannot be assigned to the mutable type 'string[]'. + } + + declare function inferTwoArguments(first: Tagged, second: Tagged): [A, B]; + const twoArguments = inferTwoArguments({ type: "a", value: 42 }, { type: "b", value: true }); + + declare function inferInlineUnion(value: { type: "a"; value: A } | { type: "b"; value: B }): [A, B]; + const oneArgument = inferInlineUnion({ type: "a", value: 42 }); + const unionArgument = inferInlineUnion(taggedSource); + const explicitUnionArgument = inferInlineUnion(taggedSource); + const reversedSourceUnion = inferInlineUnion(reversedTaggedSource); + const broadTargetUnion = inferInlineUnion(broadSourceTag); + ~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ type: string; value: number; }' is not assignable to parameter of type '{ type: "a"; value: number; } | { type: "b"; value: number; }'. +!!! error TS2345: Type '{ type: string; value: number; }' is not assignable to type '{ type: "b"; value: number; }'. +!!! error TS2345: Types of property 'type' are incompatible. +!!! error TS2345: Type 'string' is not assignable to type '"b"'. + const missingTargetUnion = inferInlineUnion(missingTag); + ~~~~~~~~~~ +!!! error TS2345: Argument of type '{ value: number; }' is not assignable to parameter of type '{ type: "a"; value: number; } | { type: "b"; value: number; }'. +!!! error TS2345: Property 'type' is missing in type '{ value: number; }' but required in type '{ type: "b"; value: number; }'. +!!! related TS2728 inferenceDiscriminatedUnions1.ts:126:76: 'type' is declared here. + + declare function inferUnionWithFallback(value: T | Tagged): [T, A, B]; + const nakedTypeParameter = inferUnionWithFallback({ type: "a", value: 42 }); + + declare function inferNoInferOverloads(first: Tagged>, second: Tagged): [A, B]; + declare function inferNoInferOverloads(first: Tagged, B>, second: Tagged): [A, B]; + const noInferArguments = inferNoInferOverloads({ type: "a", value: 42 }, { type: "b", value: true }); + const noInferReversedArguments = inferNoInferOverloads({ type: "b", value: true }, { type: "a", value: 42 }); + + declare function inferReversedUnion(value: { type: "b"; value: B } | { type: "a"; value: A }): [A, B]; + const reversedTargetUnion = inferReversedUnion(taggedSource); + + declare function inferTwoDiscriminants(value: { type: "a"; sub: 1; value: A } | { type: "b"; sub: 2; value: B }): [A, B]; + const unmatchedTargetUnion = inferTwoDiscriminants({ type: "a", sub: 2, value: 42 }); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ type: "a"; sub: 2; value: number; }' is not assignable to parameter of type '{ type: "a"; sub: 1; value: number; } | { type: "b"; sub: 2; value: unknown; }'. +!!! error TS2345: Types of property 'sub' are incompatible. +!!! error TS2345: Type '2' is not assignable to type '1'. + const unmatchedTargetUnionReversedSource = inferTwoDiscriminants({ sub: 2, type: "a", value: 42 }); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ sub: 2; type: "a"; value: number; }' is not assignable to parameter of type '{ type: "a"; sub: 1; value: unknown; } | { type: "b"; sub: 2; value: number; }'. +!!! error TS2345: Types of property 'type' are incompatible. +!!! error TS2345: Type '"a"' is not assignable to type '"b"'. + + declare function inferTwoDiscriminantsReversed(value: { sub: 1; type: "a"; value: A } | { sub: 2; type: "b"; value: B }): [A, B]; + const unmatchedTargetUnionReversed = inferTwoDiscriminantsReversed({ type: "a", sub: 2, value: 42 }); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ type: "a"; sub: 2; value: number; }' is not assignable to parameter of type '{ sub: 1; type: "a"; value: number; } | { sub: 2; type: "b"; value: unknown; }'. +!!! error TS2345: Types of property 'sub' are incompatible. +!!! error TS2345: Type '2' is not assignable to type '1'. + + declare function inferOptionalUnion(value: { type?: "a"; value: A } | { type?: "b"; value: B }): [A, B]; + const optionalTargetUnion = inferOptionalUnion(optionalTag); + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=true).symbols b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=true).symbols new file mode 100644 index 0000000000000..303db88275506 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=true).symbols @@ -0,0 +1,758 @@ +//// [tests/cases/compiler/inferenceDiscriminatedUnions1.ts] //// + +=== inferenceDiscriminatedUnions1.ts === +type Ok = { ok: true; value: T }; +>Ok : Symbol(Ok, Decl(inferenceDiscriminatedUnions1.ts, 0, 0)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 0, 8)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 0, 14)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 0, 24)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 0, 8)) + +type Err = { ok: false; value: E }; +>Err : Symbol(Err, Decl(inferenceDiscriminatedUnions1.ts, 0, 36)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 1, 9)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 1, 15)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 1, 26)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 1, 9)) + +type ErrShape = { ok: false; value: string }; +>ErrShape : Symbol(ErrShape, Decl(inferenceDiscriminatedUnions1.ts, 1, 38)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 2, 17)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 2, 28)) + +type OkShape = { ok: true; value: string[] }; +>OkShape : Symbol(OkShape, Decl(inferenceDiscriminatedUnions1.ts, 2, 45)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 3, 16)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 3, 26)) + +enum K { A, B } +>K : Symbol(K, Decl(inferenceDiscriminatedUnions1.ts, 3, 45)) +>A : Symbol(K.A, Decl(inferenceDiscriminatedUnions1.ts, 4, 8)) +>B : Symbol(K.B, Decl(inferenceDiscriminatedUnions1.ts, 4, 11)) + +type Success = { kind: "success"; value: T }; +>Success : Symbol(Success, Decl(inferenceDiscriminatedUnions1.ts, 4, 15)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 5, 13)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 5, 19)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 5, 36)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 5, 13)) + +type Failure = { kind: "failure"; value: E }; +>Failure : Symbol(Failure, Decl(inferenceDiscriminatedUnions1.ts, 5, 48)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 6, 13)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 6, 19)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 6, 36)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 6, 13)) + +type Accepted = { kind: 1; value: T }; +>Accepted : Symbol(Accepted, Decl(inferenceDiscriminatedUnions1.ts, 6, 48)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 7, 14)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 7, 20)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 7, 29)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 7, 14)) + +type Rejected = { kind: 0; value: E }; +>Rejected : Symbol(Rejected, Decl(inferenceDiscriminatedUnions1.ts, 7, 41)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 8, 14)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 8, 20)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 8, 29)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 8, 14)) + +type OptionalOk = { ok?: true; value: T }; +>OptionalOk : Symbol(OptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 8, 41)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 9, 16)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 9, 22)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 9, 33)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 9, 16)) + +type MaybeErr = { ok?: false; value: E }; +>MaybeErr : Symbol(MaybeErr, Decl(inferenceDiscriminatedUnions1.ts, 9, 45)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 10, 14)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 10, 20)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 10, 32)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 10, 14)) + +type ExplicitOptionalOk = { ok?: true | undefined; value: T }; +>ExplicitOptionalOk : Symbol(ExplicitOptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 10, 44)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 11, 24)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 11, 30)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 11, 53)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 11, 24)) + +type UnionOk = { ok: true | undefined; value: T }; +>UnionOk : Symbol(UnionOk, Decl(inferenceDiscriminatedUnions1.ts, 11, 65)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 12, 13)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 12, 19)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 12, 41)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 12, 13)) + +type AlwaysUndefinedErr = { ok: undefined; value: E }; +>AlwaysUndefinedErr : Symbol(AlwaysUndefinedErr, Decl(inferenceDiscriminatedUnions1.ts, 12, 53)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 13, 24)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 13, 30)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 13, 45)) +>E : Symbol(E, Decl(inferenceDiscriminatedUnions1.ts, 13, 24)) + +type UndefinedOk = { ok: undefined; value: T }; +>UndefinedOk : Symbol(UndefinedOk, Decl(inferenceDiscriminatedUnions1.ts, 13, 57)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 14, 17)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 14, 23)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 14, 38)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 14, 17)) + +type Tagged = { type: "a"; value: A } | { type: "b"; value: B }; +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 15, 12)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 15, 14)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 15, 21)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 15, 32)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 15, 12)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 15, 47)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 15, 58)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 15, 14)) + +declare const u1: { kind: "b"; value: number } | { kind: "a"; value: string }; +>u1 : Symbol(u1, Decl(inferenceDiscriminatedUnions1.ts, 17, 13)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 17, 19)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 17, 30)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 17, 50)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 17, 61)) + +declare const u2: { kind: string; value: number } | { kind: "a"; value: string }; +>u2 : Symbol(u2, Decl(inferenceDiscriminatedUnions1.ts, 18, 13)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 18, 19)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 18, 33)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 18, 53)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 18, 64)) + +declare const broadTag: { kind: number; value: number } | { kind: "a"; value: string }; +>broadTag : Symbol(broadTag, Decl(inferenceDiscriminatedUnions1.ts, 19, 13)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 19, 25)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 19, 39)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 19, 59)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 19, 70)) + +declare const u3: { value: number } | { kind: "a"; value: string }; +>u3 : Symbol(u3, Decl(inferenceDiscriminatedUnions1.ts, 20, 13)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 20, 19)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 20, 39)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 20, 50)) + +declare const u4: { kind: "a"; sub: 2; value: string } | { kind: "b"; sub: 1; value: number }; +>u4 : Symbol(u4, Decl(inferenceDiscriminatedUnions1.ts, 21, 13)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 21, 19)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 21, 30)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 21, 38)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 21, 58)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 21, 69)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 21, 77)) + +declare const u5: { kind: K.B; value: number } | { kind: K.A; value: string }; +>u5 : Symbol(u5, Decl(inferenceDiscriminatedUnions1.ts, 22, 13)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 22, 19)) +>K : Symbol(K, Decl(inferenceDiscriminatedUnions1.ts, 3, 45)) +>B : Symbol(K.B, Decl(inferenceDiscriminatedUnions1.ts, 4, 11)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 22, 30)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 22, 50)) +>K : Symbol(K, Decl(inferenceDiscriminatedUnions1.ts, 3, 45)) +>A : Symbol(K.A, Decl(inferenceDiscriminatedUnions1.ts, 4, 8)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 22, 61)) + +declare const u6: Err | Ok; +>u6 : Symbol(u6, Decl(inferenceDiscriminatedUnions1.ts, 23, 13)) +>Err : Symbol(Err, Decl(inferenceDiscriminatedUnions1.ts, 0, 36)) +>Ok : Symbol(Ok, Decl(inferenceDiscriminatedUnions1.ts, 0, 0)) + +declare const taggedSource: Tagged; +>taggedSource : Symbol(taggedSource, Decl(inferenceDiscriminatedUnions1.ts, 24, 13)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) + +declare const reversedTaggedSource: { type: "b"; value: number } | { type: "a"; value: string }; +>reversedTaggedSource : Symbol(reversedTaggedSource, Decl(inferenceDiscriminatedUnions1.ts, 25, 13)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 25, 37)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 25, 48)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 25, 68)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 25, 79)) + +declare const broadSourceTag: { type: string; value: number }; +>broadSourceTag : Symbol(broadSourceTag, Decl(inferenceDiscriminatedUnions1.ts, 26, 13)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 26, 31)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 26, 45)) + +declare const missingTag: { value: number }; +>missingTag : Symbol(missingTag, Decl(inferenceDiscriminatedUnions1.ts, 27, 13)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 27, 27)) + +declare const optionalTag: { type?: "a"; value: string }; +>optionalTag : Symbol(optionalTag, Decl(inferenceDiscriminatedUnions1.ts, 28, 13)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 28, 28)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 28, 40)) + +declare function ok(value: T): Ok; +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 28, 57)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 30, 20)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 30, 29)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 30, 20)) +>Ok : Symbol(Ok, Decl(inferenceDiscriminatedUnions1.ts, 0, 0)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 30, 20)) + +export function aliasTarget(): ErrShape | OkShape { return ok([]); } +>aliasTarget : Symbol(aliasTarget, Decl(inferenceDiscriminatedUnions1.ts, 30, 46)) +>ErrShape : Symbol(ErrShape, Decl(inferenceDiscriminatedUnions1.ts, 1, 38)) +>OkShape : Symbol(OkShape, Decl(inferenceDiscriminatedUnions1.ts, 2, 45)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 28, 57)) + +export function f(): Ok | Err { +>f : Symbol(f, Decl(inferenceDiscriminatedUnions1.ts, 31, 68)) +>Ok : Symbol(Ok, Decl(inferenceDiscriminatedUnions1.ts, 0, 0)) +>Err : Symbol(Err, Decl(inferenceDiscriminatedUnions1.ts, 0, 36)) + + return ok([]); +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 28, 57)) +} + +export function optionalSource(): Ok | MaybeErr { +>optionalSource : Symbol(optionalSource, Decl(inferenceDiscriminatedUnions1.ts, 35, 1)) +>Ok : Symbol(Ok, Decl(inferenceDiscriminatedUnions1.ts, 0, 0)) +>MaybeErr : Symbol(MaybeErr, Decl(inferenceDiscriminatedUnions1.ts, 9, 45)) + + return ok([]); +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 28, 57)) +} + +declare function okInline(value: T): { ok: true; value: T }; +>okInline : Symbol(okInline, Decl(inferenceDiscriminatedUnions1.ts, 39, 1)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 41, 26)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 41, 35)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 41, 26)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 41, 47)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 41, 57)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 41, 26)) + +export function inlineTarget(): ErrShape | OkShape { return okInline([]); } +>inlineTarget : Symbol(inlineTarget, Decl(inferenceDiscriminatedUnions1.ts, 41, 69)) +>ErrShape : Symbol(ErrShape, Decl(inferenceDiscriminatedUnions1.ts, 1, 38)) +>OkShape : Symbol(OkShape, Decl(inferenceDiscriminatedUnions1.ts, 2, 45)) +>okInline : Symbol(okInline, Decl(inferenceDiscriminatedUnions1.ts, 39, 1)) + +export function inlineTargetReversed(): OkShape | ErrShape { return okInline([]); } +>inlineTargetReversed : Symbol(inlineTargetReversed, Decl(inferenceDiscriminatedUnions1.ts, 42, 75)) +>OkShape : Symbol(OkShape, Decl(inferenceDiscriminatedUnions1.ts, 2, 45)) +>ErrShape : Symbol(ErrShape, Decl(inferenceDiscriminatedUnions1.ts, 1, 38)) +>okInline : Symbol(okInline, Decl(inferenceDiscriminatedUnions1.ts, 39, 1)) + +declare function on(handler: (e: { kind: "a"; value: T }) => void): T; +>on : Symbol(on, Decl(inferenceDiscriminatedUnions1.ts, 44, 83)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 46, 20)) +>handler : Symbol(handler, Decl(inferenceDiscriminatedUnions1.ts, 46, 23)) +>e : Symbol(e, Decl(inferenceDiscriminatedUnions1.ts, 46, 33)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 46, 37)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 46, 48)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 46, 20)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 46, 20)) + +const r1 = on((e: { kind: "a"; value: string } | { kind: "b"; value: number }) => {}); +>r1 : Symbol(r1, Decl(inferenceDiscriminatedUnions1.ts, 47, 5)) +>on : Symbol(on, Decl(inferenceDiscriminatedUnions1.ts, 44, 83)) +>e : Symbol(e, Decl(inferenceDiscriminatedUnions1.ts, 47, 15)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 47, 19)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 47, 30)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 47, 50)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 47, 61)) + +const r2 = on((e: { kind: "b"; value: number } | { kind: "a"; value: string }) => {}); +>r2 : Symbol(r2, Decl(inferenceDiscriminatedUnions1.ts, 48, 5)) +>on : Symbol(on, Decl(inferenceDiscriminatedUnions1.ts, 44, 83)) +>e : Symbol(e, Decl(inferenceDiscriminatedUnions1.ts, 48, 15)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 48, 19)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 48, 30)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 48, 50)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 48, 61)) + +declare function pick(x: { kind: "a"; value: T }): T; +>pick : Symbol(pick, Decl(inferenceDiscriminatedUnions1.ts, 48, 86)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 50, 22)) +>x : Symbol(x, Decl(inferenceDiscriminatedUnions1.ts, 50, 25)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 50, 29)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 50, 40)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 50, 22)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 50, 22)) + +const r3 = pick(u1); +>r3 : Symbol(r3, Decl(inferenceDiscriminatedUnions1.ts, 51, 5)) +>pick : Symbol(pick, Decl(inferenceDiscriminatedUnions1.ts, 48, 86)) +>u1 : Symbol(u1, Decl(inferenceDiscriminatedUnions1.ts, 17, 13)) + +const r4 = pick(u2); +>r4 : Symbol(r4, Decl(inferenceDiscriminatedUnions1.ts, 52, 5)) +>pick : Symbol(pick, Decl(inferenceDiscriminatedUnions1.ts, 48, 86)) +>u2 : Symbol(u2, Decl(inferenceDiscriminatedUnions1.ts, 18, 13)) + +const broadResult = pick(broadTag); +>broadResult : Symbol(broadResult, Decl(inferenceDiscriminatedUnions1.ts, 53, 5)) +>pick : Symbol(pick, Decl(inferenceDiscriminatedUnions1.ts, 48, 86)) +>broadTag : Symbol(broadTag, Decl(inferenceDiscriminatedUnions1.ts, 19, 13)) + +const r5 = pick(u3); +>r5 : Symbol(r5, Decl(inferenceDiscriminatedUnions1.ts, 54, 5)) +>pick : Symbol(pick, Decl(inferenceDiscriminatedUnions1.ts, 48, 86)) +>u3 : Symbol(u3, Decl(inferenceDiscriminatedUnions1.ts, 20, 13)) + +declare function two(x: { kind: "a"; sub: 1; value: T }): T; +>two : Symbol(two, Decl(inferenceDiscriminatedUnions1.ts, 54, 20)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 56, 21)) +>x : Symbol(x, Decl(inferenceDiscriminatedUnions1.ts, 56, 24)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 56, 28)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 56, 39)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 56, 47)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 56, 21)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 56, 21)) + +const r6 = two(u4); +>r6 : Symbol(r6, Decl(inferenceDiscriminatedUnions1.ts, 57, 5)) +>two : Symbol(two, Decl(inferenceDiscriminatedUnions1.ts, 54, 20)) +>u4 : Symbol(u4, Decl(inferenceDiscriminatedUnions1.ts, 21, 13)) + +declare function twoReversed(x: { sub: 1; kind: "a"; value: T }): T; +>twoReversed : Symbol(twoReversed, Decl(inferenceDiscriminatedUnions1.ts, 57, 19)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 59, 29)) +>x : Symbol(x, Decl(inferenceDiscriminatedUnions1.ts, 59, 32)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 59, 36)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 59, 44)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 59, 55)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 59, 29)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 59, 29)) + +const r6Reversed = twoReversed(u4); +>r6Reversed : Symbol(r6Reversed, Decl(inferenceDiscriminatedUnions1.ts, 60, 5)) +>twoReversed : Symbol(twoReversed, Decl(inferenceDiscriminatedUnions1.ts, 57, 19)) +>u4 : Symbol(u4, Decl(inferenceDiscriminatedUnions1.ts, 21, 13)) + +declare function enumTag(x: { kind: K.A; value: T }): T; +>enumTag : Symbol(enumTag, Decl(inferenceDiscriminatedUnions1.ts, 60, 35)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 62, 25)) +>x : Symbol(x, Decl(inferenceDiscriminatedUnions1.ts, 62, 28)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 62, 32)) +>K : Symbol(K, Decl(inferenceDiscriminatedUnions1.ts, 3, 45)) +>A : Symbol(K.A, Decl(inferenceDiscriminatedUnions1.ts, 4, 8)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 62, 43)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 62, 25)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 62, 25)) + +const r7 = enumTag(u5); +>r7 : Symbol(r7, Decl(inferenceDiscriminatedUnions1.ts, 63, 5)) +>enumTag : Symbol(enumTag, Decl(inferenceDiscriminatedUnions1.ts, 60, 35)) +>u5 : Symbol(u5, Decl(inferenceDiscriminatedUnions1.ts, 22, 13)) + +declare function boolTag(x: { ok: boolean; value: T }): T; +>boolTag : Symbol(boolTag, Decl(inferenceDiscriminatedUnions1.ts, 63, 23)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 65, 25)) +>x : Symbol(x, Decl(inferenceDiscriminatedUnions1.ts, 65, 28)) +>ok : Symbol(ok, Decl(inferenceDiscriminatedUnions1.ts, 65, 32)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 65, 45)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 65, 25)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 65, 25)) + +const r8 = boolTag(u6); +>r8 : Symbol(r8, Decl(inferenceDiscriminatedUnions1.ts, 66, 5)) +>boolTag : Symbol(boolTag, Decl(inferenceDiscriminatedUnions1.ts, 63, 23)) +>u6 : Symbol(u6, Decl(inferenceDiscriminatedUnions1.ts, 23, 13)) + +declare function wrap(value: T): { result: Ok }; +>wrap : Symbol(wrap, Decl(inferenceDiscriminatedUnions1.ts, 66, 23)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 68, 22)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 68, 31)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 68, 22)) +>result : Symbol(result, Decl(inferenceDiscriminatedUnions1.ts, 68, 43)) +>Ok : Symbol(Ok, Decl(inferenceDiscriminatedUnions1.ts, 0, 0)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 68, 22)) + +export function nested(): { result: ErrShape | OkShape } { return wrap([]); } +>nested : Symbol(nested, Decl(inferenceDiscriminatedUnions1.ts, 68, 60)) +>result : Symbol(result, Decl(inferenceDiscriminatedUnions1.ts, 69, 27)) +>ErrShape : Symbol(ErrShape, Decl(inferenceDiscriminatedUnions1.ts, 1, 38)) +>OkShape : Symbol(OkShape, Decl(inferenceDiscriminatedUnions1.ts, 2, 45)) +>wrap : Symbol(wrap, Decl(inferenceDiscriminatedUnions1.ts, 66, 23)) + +declare function success(value: T): Success; +>success : Symbol(success, Decl(inferenceDiscriminatedUnions1.ts, 69, 77)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 71, 25)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 71, 34)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 71, 25)) +>Success : Symbol(Success, Decl(inferenceDiscriminatedUnions1.ts, 4, 15)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 71, 25)) + +export function withStringTag(): Success | Failure { +>withStringTag : Symbol(withStringTag, Decl(inferenceDiscriminatedUnions1.ts, 71, 56)) +>Success : Symbol(Success, Decl(inferenceDiscriminatedUnions1.ts, 4, 15)) +>Failure : Symbol(Failure, Decl(inferenceDiscriminatedUnions1.ts, 5, 48)) + + return success([]); +>success : Symbol(success, Decl(inferenceDiscriminatedUnions1.ts, 69, 77)) +} + +declare function accepted(value: T): Accepted; +>accepted : Symbol(accepted, Decl(inferenceDiscriminatedUnions1.ts, 74, 1)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 76, 26)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 76, 35)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 76, 26)) +>Accepted : Symbol(Accepted, Decl(inferenceDiscriminatedUnions1.ts, 6, 48)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 76, 26)) + +export function withNumberTag(): Accepted | Rejected { +>withNumberTag : Symbol(withNumberTag, Decl(inferenceDiscriminatedUnions1.ts, 76, 58)) +>Accepted : Symbol(Accepted, Decl(inferenceDiscriminatedUnions1.ts, 6, 48)) +>Rejected : Symbol(Rejected, Decl(inferenceDiscriminatedUnions1.ts, 7, 41)) + + return accepted([]); +>accepted : Symbol(accepted, Decl(inferenceDiscriminatedUnions1.ts, 74, 1)) +} + +declare function unmatched(): { kind: "other"; value: T }; +>unmatched : Symbol(unmatched, Decl(inferenceDiscriminatedUnions1.ts, 79, 1)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 81, 27)) +>kind : Symbol(kind, Decl(inferenceDiscriminatedUnions1.ts, 81, 34)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 81, 49)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 81, 27)) + +export function withUnmatchedTag(): Success | Failure { +>withUnmatchedTag : Symbol(withUnmatchedTag, Decl(inferenceDiscriminatedUnions1.ts, 81, 61)) +>Success : Symbol(Success, Decl(inferenceDiscriminatedUnions1.ts, 4, 15)) +>Failure : Symbol(Failure, Decl(inferenceDiscriminatedUnions1.ts, 5, 48)) + + return unmatched(); +>unmatched : Symbol(unmatched, Decl(inferenceDiscriminatedUnions1.ts, 79, 1)) +} + +declare function optionalOk(value: T): OptionalOk; +>optionalOk : Symbol(optionalOk, Decl(inferenceDiscriminatedUnions1.ts, 84, 1)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 86, 28)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 86, 37)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 86, 28)) +>OptionalOk : Symbol(OptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 8, 41)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 86, 28)) + +export function optionalTarget(): OptionalOk | Err { +>optionalTarget : Symbol(optionalTarget, Decl(inferenceDiscriminatedUnions1.ts, 86, 62)) +>OptionalOk : Symbol(OptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 8, 41)) +>Err : Symbol(Err, Decl(inferenceDiscriminatedUnions1.ts, 0, 36)) + + return optionalOk([]); +>optionalOk : Symbol(optionalOk, Decl(inferenceDiscriminatedUnions1.ts, 84, 1)) +} + +export function bothOptional(): OptionalOk | MaybeErr { +>bothOptional : Symbol(bothOptional, Decl(inferenceDiscriminatedUnions1.ts, 89, 1)) +>OptionalOk : Symbol(OptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 8, 41)) +>MaybeErr : Symbol(MaybeErr, Decl(inferenceDiscriminatedUnions1.ts, 9, 45)) + + return optionalOk([]); +>optionalOk : Symbol(optionalOk, Decl(inferenceDiscriminatedUnions1.ts, 84, 1)) +} + +export function missingSourceTag(): OptionalOk | { value: string } { +>missingSourceTag : Symbol(missingSourceTag, Decl(inferenceDiscriminatedUnions1.ts, 93, 1)) +>OptionalOk : Symbol(OptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 8, 41)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 95, 60)) + + return optionalOk([]); +>optionalOk : Symbol(optionalOk, Decl(inferenceDiscriminatedUnions1.ts, 84, 1)) +} + +export function undefinedSource(): OptionalOk | AlwaysUndefinedErr { +>undefinedSource : Symbol(undefinedSource, Decl(inferenceDiscriminatedUnions1.ts, 97, 1)) +>OptionalOk : Symbol(OptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 8, 41)) +>AlwaysUndefinedErr : Symbol(AlwaysUndefinedErr, Decl(inferenceDiscriminatedUnions1.ts, 12, 53)) + + return optionalOk([]); +>optionalOk : Symbol(optionalOk, Decl(inferenceDiscriminatedUnions1.ts, 84, 1)) +} + +declare function explicitOptionalOk(value: T): ExplicitOptionalOk; +>explicitOptionalOk : Symbol(explicitOptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 101, 1)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 103, 36)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 103, 45)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 103, 36)) +>ExplicitOptionalOk : Symbol(ExplicitOptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 10, 44)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 103, 36)) + +export function explicitUndefined(): ExplicitOptionalOk | Err { +>explicitUndefined : Symbol(explicitUndefined, Decl(inferenceDiscriminatedUnions1.ts, 103, 78)) +>ExplicitOptionalOk : Symbol(ExplicitOptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 10, 44)) +>Err : Symbol(Err, Decl(inferenceDiscriminatedUnions1.ts, 0, 36)) + + return explicitOptionalOk([]); +>explicitOptionalOk : Symbol(explicitOptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 101, 1)) +} + +export function explicitUndefinedOverlap(): ExplicitOptionalOk | AlwaysUndefinedErr { +>explicitUndefinedOverlap : Symbol(explicitUndefinedOverlap, Decl(inferenceDiscriminatedUnions1.ts, 106, 1)) +>ExplicitOptionalOk : Symbol(ExplicitOptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 10, 44)) +>AlwaysUndefinedErr : Symbol(AlwaysUndefinedErr, Decl(inferenceDiscriminatedUnions1.ts, 12, 53)) + + return explicitOptionalOk([]); +>explicitOptionalOk : Symbol(explicitOptionalOk, Decl(inferenceDiscriminatedUnions1.ts, 101, 1)) +} + +declare function unionOk(value: T): UnionOk; +>unionOk : Symbol(unionOk, Decl(inferenceDiscriminatedUnions1.ts, 110, 1)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 112, 25)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 112, 34)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 112, 25)) +>UnionOk : Symbol(UnionOk, Decl(inferenceDiscriminatedUnions1.ts, 11, 65)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 112, 25)) + +export function requiredUnionTag(): UnionOk | Err { +>requiredUnionTag : Symbol(requiredUnionTag, Decl(inferenceDiscriminatedUnions1.ts, 112, 56)) +>UnionOk : Symbol(UnionOk, Decl(inferenceDiscriminatedUnions1.ts, 11, 65)) +>Err : Symbol(Err, Decl(inferenceDiscriminatedUnions1.ts, 0, 36)) + + return unionOk([]); +>unionOk : Symbol(unionOk, Decl(inferenceDiscriminatedUnions1.ts, 110, 1)) +} + +declare function undefinedOk(value: T): UndefinedOk; +>undefinedOk : Symbol(undefinedOk, Decl(inferenceDiscriminatedUnions1.ts, 115, 1)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 117, 29)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 117, 38)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 117, 29)) +>UndefinedOk : Symbol(UndefinedOk, Decl(inferenceDiscriminatedUnions1.ts, 13, 57)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 117, 29)) + +export function undefinedTarget(): UndefinedOk | MaybeErr { +>undefinedTarget : Symbol(undefinedTarget, Decl(inferenceDiscriminatedUnions1.ts, 117, 64)) +>UndefinedOk : Symbol(UndefinedOk, Decl(inferenceDiscriminatedUnions1.ts, 13, 57)) +>MaybeErr : Symbol(MaybeErr, Decl(inferenceDiscriminatedUnions1.ts, 9, 45)) + + return undefinedOk([]); +>undefinedOk : Symbol(undefinedOk, Decl(inferenceDiscriminatedUnions1.ts, 115, 1)) +} + +declare function inferTwoArguments(first: Tagged, second: Tagged): [A, B]; +>inferTwoArguments : Symbol(inferTwoArguments, Decl(inferenceDiscriminatedUnions1.ts, 120, 1)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 122, 35)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 122, 37)) +>first : Symbol(first, Decl(inferenceDiscriminatedUnions1.ts, 122, 41)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 122, 35)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 122, 37)) +>second : Symbol(second, Decl(inferenceDiscriminatedUnions1.ts, 122, 61)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 122, 35)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 122, 37)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 122, 35)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 122, 37)) + +const twoArguments = inferTwoArguments({ type: "a", value: 42 }, { type: "b", value: true }); +>twoArguments : Symbol(twoArguments, Decl(inferenceDiscriminatedUnions1.ts, 123, 5)) +>inferTwoArguments : Symbol(inferTwoArguments, Decl(inferenceDiscriminatedUnions1.ts, 120, 1)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 123, 40)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 123, 51)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 123, 66)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 123, 77)) + +declare function inferInlineUnion(value: { type: "a"; value: A } | { type: "b"; value: B }): [A, B]; +>inferInlineUnion : Symbol(inferInlineUnion, Decl(inferenceDiscriminatedUnions1.ts, 123, 93)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 125, 34)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 125, 36)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 125, 40)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 125, 48)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 125, 59)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 125, 34)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 125, 74)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 125, 85)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 125, 36)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 125, 34)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 125, 36)) + +const oneArgument = inferInlineUnion({ type: "a", value: 42 }); +>oneArgument : Symbol(oneArgument, Decl(inferenceDiscriminatedUnions1.ts, 126, 5)) +>inferInlineUnion : Symbol(inferInlineUnion, Decl(inferenceDiscriminatedUnions1.ts, 123, 93)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 126, 38)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 126, 49)) + +const unionArgument = inferInlineUnion(taggedSource); +>unionArgument : Symbol(unionArgument, Decl(inferenceDiscriminatedUnions1.ts, 127, 5)) +>inferInlineUnion : Symbol(inferInlineUnion, Decl(inferenceDiscriminatedUnions1.ts, 123, 93)) +>taggedSource : Symbol(taggedSource, Decl(inferenceDiscriminatedUnions1.ts, 24, 13)) + +const explicitUnionArgument = inferInlineUnion(taggedSource); +>explicitUnionArgument : Symbol(explicitUnionArgument, Decl(inferenceDiscriminatedUnions1.ts, 128, 5)) +>inferInlineUnion : Symbol(inferInlineUnion, Decl(inferenceDiscriminatedUnions1.ts, 123, 93)) +>taggedSource : Symbol(taggedSource, Decl(inferenceDiscriminatedUnions1.ts, 24, 13)) + +const reversedSourceUnion = inferInlineUnion(reversedTaggedSource); +>reversedSourceUnion : Symbol(reversedSourceUnion, Decl(inferenceDiscriminatedUnions1.ts, 129, 5)) +>inferInlineUnion : Symbol(inferInlineUnion, Decl(inferenceDiscriminatedUnions1.ts, 123, 93)) +>reversedTaggedSource : Symbol(reversedTaggedSource, Decl(inferenceDiscriminatedUnions1.ts, 25, 13)) + +const broadTargetUnion = inferInlineUnion(broadSourceTag); +>broadTargetUnion : Symbol(broadTargetUnion, Decl(inferenceDiscriminatedUnions1.ts, 130, 5)) +>inferInlineUnion : Symbol(inferInlineUnion, Decl(inferenceDiscriminatedUnions1.ts, 123, 93)) +>broadSourceTag : Symbol(broadSourceTag, Decl(inferenceDiscriminatedUnions1.ts, 26, 13)) + +const missingTargetUnion = inferInlineUnion(missingTag); +>missingTargetUnion : Symbol(missingTargetUnion, Decl(inferenceDiscriminatedUnions1.ts, 131, 5)) +>inferInlineUnion : Symbol(inferInlineUnion, Decl(inferenceDiscriminatedUnions1.ts, 123, 93)) +>missingTag : Symbol(missingTag, Decl(inferenceDiscriminatedUnions1.ts, 27, 13)) + +declare function inferUnionWithFallback(value: T | Tagged): [T, A, B]; +>inferUnionWithFallback : Symbol(inferUnionWithFallback, Decl(inferenceDiscriminatedUnions1.ts, 131, 56)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 133, 40)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 133, 51)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 133, 70)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 133, 73)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 133, 77)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 133, 40)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 133, 70)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 133, 73)) +>T : Symbol(T, Decl(inferenceDiscriminatedUnions1.ts, 133, 40)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 133, 70)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 133, 73)) + +const nakedTypeParameter = inferUnionWithFallback({ type: "a", value: 42 }); +>nakedTypeParameter : Symbol(nakedTypeParameter, Decl(inferenceDiscriminatedUnions1.ts, 134, 5)) +>inferUnionWithFallback : Symbol(inferUnionWithFallback, Decl(inferenceDiscriminatedUnions1.ts, 131, 56)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 134, 51)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 134, 62)) + +declare function inferNoInferOverloads(first: Tagged>, second: Tagged): [A, B]; +>inferNoInferOverloads : Symbol(inferNoInferOverloads, Decl(inferenceDiscriminatedUnions1.ts, 134, 76), Decl(inferenceDiscriminatedUnions1.ts, 136, 105)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 136, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 136, 41)) +>first : Symbol(first, Decl(inferenceDiscriminatedUnions1.ts, 136, 45)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 136, 39)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 136, 41)) +>second : Symbol(second, Decl(inferenceDiscriminatedUnions1.ts, 136, 74)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 136, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 136, 41)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 136, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 136, 41)) + +declare function inferNoInferOverloads(first: Tagged, B>, second: Tagged): [A, B]; +>inferNoInferOverloads : Symbol(inferNoInferOverloads, Decl(inferenceDiscriminatedUnions1.ts, 134, 76), Decl(inferenceDiscriminatedUnions1.ts, 136, 105)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 137, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 137, 41)) +>first : Symbol(first, Decl(inferenceDiscriminatedUnions1.ts, 137, 45)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 137, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 137, 41)) +>second : Symbol(second, Decl(inferenceDiscriminatedUnions1.ts, 137, 74)) +>Tagged : Symbol(Tagged, Decl(inferenceDiscriminatedUnions1.ts, 14, 50)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 137, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 137, 41)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 137, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 137, 41)) + +const noInferArguments = inferNoInferOverloads({ type: "a", value: 42 }, { type: "b", value: true }); +>noInferArguments : Symbol(noInferArguments, Decl(inferenceDiscriminatedUnions1.ts, 138, 5)) +>inferNoInferOverloads : Symbol(inferNoInferOverloads, Decl(inferenceDiscriminatedUnions1.ts, 134, 76), Decl(inferenceDiscriminatedUnions1.ts, 136, 105)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 138, 48)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 138, 59)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 138, 74)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 138, 85)) + +const noInferReversedArguments = inferNoInferOverloads({ type: "b", value: true }, { type: "a", value: 42 }); +>noInferReversedArguments : Symbol(noInferReversedArguments, Decl(inferenceDiscriminatedUnions1.ts, 139, 5)) +>inferNoInferOverloads : Symbol(inferNoInferOverloads, Decl(inferenceDiscriminatedUnions1.ts, 134, 76), Decl(inferenceDiscriminatedUnions1.ts, 136, 105)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 139, 56)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 139, 67)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 139, 84)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 139, 95)) + +declare function inferReversedUnion(value: { type: "b"; value: B } | { type: "a"; value: A }): [A, B]; +>inferReversedUnion : Symbol(inferReversedUnion, Decl(inferenceDiscriminatedUnions1.ts, 139, 109)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 141, 36)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 141, 38)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 141, 42)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 141, 50)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 141, 61)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 141, 38)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 141, 76)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 141, 87)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 141, 36)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 141, 36)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 141, 38)) + +const reversedTargetUnion = inferReversedUnion(taggedSource); +>reversedTargetUnion : Symbol(reversedTargetUnion, Decl(inferenceDiscriminatedUnions1.ts, 142, 5)) +>inferReversedUnion : Symbol(inferReversedUnion, Decl(inferenceDiscriminatedUnions1.ts, 139, 109)) +>taggedSource : Symbol(taggedSource, Decl(inferenceDiscriminatedUnions1.ts, 24, 13)) + +declare function inferTwoDiscriminants(value: { type: "a"; sub: 1; value: A } | { type: "b"; sub: 2; value: B }): [A, B]; +>inferTwoDiscriminants : Symbol(inferTwoDiscriminants, Decl(inferenceDiscriminatedUnions1.ts, 142, 61)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 144, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 144, 41)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 144, 45)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 144, 53)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 144, 64)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 144, 72)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 144, 39)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 144, 87)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 144, 98)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 144, 106)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 144, 41)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 144, 39)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 144, 41)) + +const unmatchedTargetUnion = inferTwoDiscriminants({ type: "a", sub: 2, value: 42 }); +>unmatchedTargetUnion : Symbol(unmatchedTargetUnion, Decl(inferenceDiscriminatedUnions1.ts, 145, 5)) +>inferTwoDiscriminants : Symbol(inferTwoDiscriminants, Decl(inferenceDiscriminatedUnions1.ts, 142, 61)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 145, 52)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 145, 63)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 145, 71)) + +const unmatchedTargetUnionReversedSource = inferTwoDiscriminants({ sub: 2, type: "a", value: 42 }); +>unmatchedTargetUnionReversedSource : Symbol(unmatchedTargetUnionReversedSource, Decl(inferenceDiscriminatedUnions1.ts, 146, 5)) +>inferTwoDiscriminants : Symbol(inferTwoDiscriminants, Decl(inferenceDiscriminatedUnions1.ts, 142, 61)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 146, 66)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 146, 74)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 146, 85)) + +declare function inferTwoDiscriminantsReversed(value: { sub: 1; type: "a"; value: A } | { sub: 2; type: "b"; value: B }): [A, B]; +>inferTwoDiscriminantsReversed : Symbol(inferTwoDiscriminantsReversed, Decl(inferenceDiscriminatedUnions1.ts, 146, 99)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 148, 47)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 148, 49)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 148, 53)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 148, 61)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 148, 69)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 148, 80)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 148, 47)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 148, 95)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 148, 103)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 148, 114)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 148, 49)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 148, 47)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 148, 49)) + +const unmatchedTargetUnionReversed = inferTwoDiscriminantsReversed({ type: "a", sub: 2, value: 42 }); +>unmatchedTargetUnionReversed : Symbol(unmatchedTargetUnionReversed, Decl(inferenceDiscriminatedUnions1.ts, 149, 5)) +>inferTwoDiscriminantsReversed : Symbol(inferTwoDiscriminantsReversed, Decl(inferenceDiscriminatedUnions1.ts, 146, 99)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 149, 68)) +>sub : Symbol(sub, Decl(inferenceDiscriminatedUnions1.ts, 149, 79)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 149, 87)) + +declare function inferOptionalUnion(value: { type?: "a"; value: A } | { type?: "b"; value: B }): [A, B]; +>inferOptionalUnion : Symbol(inferOptionalUnion, Decl(inferenceDiscriminatedUnions1.ts, 149, 101)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 151, 36)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 151, 38)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 151, 42)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 151, 50)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 151, 62)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 151, 36)) +>type : Symbol(type, Decl(inferenceDiscriminatedUnions1.ts, 151, 77)) +>value : Symbol(value, Decl(inferenceDiscriminatedUnions1.ts, 151, 89)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 151, 38)) +>A : Symbol(A, Decl(inferenceDiscriminatedUnions1.ts, 151, 36)) +>B : Symbol(B, Decl(inferenceDiscriminatedUnions1.ts, 151, 38)) + +const optionalTargetUnion = inferOptionalUnion(optionalTag); +>optionalTargetUnion : Symbol(optionalTargetUnion, Decl(inferenceDiscriminatedUnions1.ts, 152, 5)) +>inferOptionalUnion : Symbol(inferOptionalUnion, Decl(inferenceDiscriminatedUnions1.ts, 149, 101)) +>optionalTag : Symbol(optionalTag, Decl(inferenceDiscriminatedUnions1.ts, 28, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=true).types b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=true).types new file mode 100644 index 0000000000000..51233ebc8cdcc --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/inferenceDiscriminatedUnions1(exactoptionalpropertytypes=true).types @@ -0,0 +1,669 @@ +//// [tests/cases/compiler/inferenceDiscriminatedUnions1.ts] //// + +=== inferenceDiscriminatedUnions1.ts === +type Ok = { ok: true; value: T }; +>Ok : Ok +>ok : true +>true : true +>value : T + +type Err = { ok: false; value: E }; +>Err : Err +>ok : false +>false : false +>value : E + +type ErrShape = { ok: false; value: string }; +>ErrShape : ErrShape +>ok : false +>false : false +>value : string + +type OkShape = { ok: true; value: string[] }; +>OkShape : OkShape +>ok : true +>true : true +>value : string[] + +enum K { A, B } +>K : K +>A : K.A +>B : K.B + +type Success = { kind: "success"; value: T }; +>Success : Success +>kind : "success" +>value : T + +type Failure = { kind: "failure"; value: E }; +>Failure : Failure +>kind : "failure" +>value : E + +type Accepted = { kind: 1; value: T }; +>Accepted : Accepted +>kind : 1 +>value : T + +type Rejected = { kind: 0; value: E }; +>Rejected : Rejected +>kind : 0 +>value : E + +type OptionalOk = { ok?: true; value: T }; +>OptionalOk : OptionalOk +>ok : true | undefined +>true : true +>value : T + +type MaybeErr = { ok?: false; value: E }; +>MaybeErr : MaybeErr +>ok : false | undefined +>false : false +>value : E + +type ExplicitOptionalOk = { ok?: true | undefined; value: T }; +>ExplicitOptionalOk : ExplicitOptionalOk +>ok : true | undefined +>true : true +>value : T + +type UnionOk = { ok: true | undefined; value: T }; +>UnionOk : UnionOk +>ok : true | undefined +>true : true +>value : T + +type AlwaysUndefinedErr = { ok: undefined; value: E }; +>AlwaysUndefinedErr : AlwaysUndefinedErr +>ok : undefined +>value : E + +type UndefinedOk = { ok: undefined; value: T }; +>UndefinedOk : UndefinedOk +>ok : undefined +>value : T + +type Tagged = { type: "a"; value: A } | { type: "b"; value: B }; +>Tagged : Tagged +>type : "a" +>value : A +>type : "b" +>value : B + +declare const u1: { kind: "b"; value: number } | { kind: "a"; value: string }; +>u1 : { kind: "b"; value: number; } | { kind: "a"; value: string; } +>kind : "b" +>value : number +>kind : "a" +>value : string + +declare const u2: { kind: string; value: number } | { kind: "a"; value: string }; +>u2 : { kind: string; value: number; } | { kind: "a"; value: string; } +>kind : string +>value : number +>kind : "a" +>value : string + +declare const broadTag: { kind: number; value: number } | { kind: "a"; value: string }; +>broadTag : { kind: number; value: number; } | { kind: "a"; value: string; } +>kind : number +>value : number +>kind : "a" +>value : string + +declare const u3: { value: number } | { kind: "a"; value: string }; +>u3 : { value: number; } | { kind: "a"; value: string; } +>value : number +>kind : "a" +>value : string + +declare const u4: { kind: "a"; sub: 2; value: string } | { kind: "b"; sub: 1; value: number }; +>u4 : { kind: "a"; sub: 2; value: string; } | { kind: "b"; sub: 1; value: number; } +>kind : "a" +>sub : 2 +>value : string +>kind : "b" +>sub : 1 +>value : number + +declare const u5: { kind: K.B; value: number } | { kind: K.A; value: string }; +>u5 : { kind: K.B; value: number; } | { kind: K.A; value: string; } +>kind : K.B +>K : any +>value : number +>kind : K.A +>K : any +>value : string + +declare const u6: Err | Ok; +>u6 : Err | Ok + +declare const taggedSource: Tagged; +>taggedSource : Tagged + +declare const reversedTaggedSource: { type: "b"; value: number } | { type: "a"; value: string }; +>reversedTaggedSource : { type: "b"; value: number; } | { type: "a"; value: string; } +>type : "b" +>value : number +>type : "a" +>value : string + +declare const broadSourceTag: { type: string; value: number }; +>broadSourceTag : { type: string; value: number; } +>type : string +>value : number + +declare const missingTag: { value: number }; +>missingTag : { value: number; } +>value : number + +declare const optionalTag: { type?: "a"; value: string }; +>optionalTag : { type?: "a"; value: string; } +>type : "a" | undefined +>value : string + +declare function ok(value: T): Ok; +>ok : (value: T) => Ok +>value : T + +export function aliasTarget(): ErrShape | OkShape { return ok([]); } +>aliasTarget : () => ErrShape | OkShape +>ok([]) : Ok<[]> +>ok : (value: T) => Ok +>[] : [] + +export function f(): Ok | Err { +>f : () => Ok | Err + + return ok([]); +>ok([]) : Ok<[]> +>ok : (value: T) => Ok +>[] : [] +} + +export function optionalSource(): Ok | MaybeErr { +>optionalSource : () => Ok | MaybeErr + + return ok([]); +>ok([]) : Ok<[]> +>ok : (value: T) => Ok +>[] : [] +} + +declare function okInline(value: T): { ok: true; value: T }; +>okInline : (value: T) => { ok: true; value: T; } +>value : T +>ok : true +>true : true +>value : T + +export function inlineTarget(): ErrShape | OkShape { return okInline([]); } +>inlineTarget : () => ErrShape | OkShape +>okInline([]) : { ok: true; value: []; } +>okInline : (value: T) => { ok: true; value: T; } +>[] : [] + +export function inlineTargetReversed(): OkShape | ErrShape { return okInline([]); } +>inlineTargetReversed : () => OkShape | ErrShape +>okInline([]) : { ok: true; value: []; } +>okInline : (value: T) => { ok: true; value: T; } +>[] : [] + +declare function on(handler: (e: { kind: "a"; value: T }) => void): T; +>on : (handler: (e: { kind: "a"; value: T; }) => void) => T +>handler : (e: { kind: "a"; value: T; }) => void +>e : { kind: "a"; value: T; } +>kind : "a" +>value : T + +const r1 = on((e: { kind: "a"; value: string } | { kind: "b"; value: number }) => {}); +>r1 : string +>on((e: { kind: "a"; value: string } | { kind: "b"; value: number }) => {}) : string +>on : (handler: (e: { kind: "a"; value: T; }) => void) => T +>(e: { kind: "a"; value: string } | { kind: "b"; value: number }) => {} : (e: { kind: "a"; value: string; } | { kind: "b"; value: number; }) => void +>e : { kind: "a"; value: string; } | { kind: "b"; value: number; } +>kind : "a" +>value : string +>kind : "b" +>value : number + +const r2 = on((e: { kind: "b"; value: number } | { kind: "a"; value: string }) => {}); +>r2 : string +>on((e: { kind: "b"; value: number } | { kind: "a"; value: string }) => {}) : string +>on : (handler: (e: { kind: "a"; value: T; }) => void) => T +>(e: { kind: "b"; value: number } | { kind: "a"; value: string }) => {} : (e: { kind: "b"; value: number; } | { kind: "a"; value: string; }) => void +>e : { kind: "b"; value: number; } | { kind: "a"; value: string; } +>kind : "b" +>value : number +>kind : "a" +>value : string + +declare function pick(x: { kind: "a"; value: T }): T; +>pick : (x: { kind: "a"; value: T; }) => T +>x : { kind: "a"; value: T; } +>kind : "a" +>value : T + +const r3 = pick(u1); +>r3 : string +>pick(u1) : string +>pick : (x: { kind: "a"; value: T; }) => T +>u1 : { kind: "b"; value: number; } | { kind: "a"; value: string; } + +const r4 = pick(u2); +>r4 : number +>pick(u2) : number +>pick : (x: { kind: "a"; value: T; }) => T +>u2 : { kind: string; value: number; } | { kind: "a"; value: string; } + +const broadResult = pick(broadTag); +>broadResult : string +>pick(broadTag) : string +>pick : (x: { kind: "a"; value: T; }) => T +>broadTag : { kind: number; value: number; } | { kind: "a"; value: string; } + +const r5 = pick(u3); +>r5 : number +>pick(u3) : number +>pick : (x: { kind: "a"; value: T; }) => T +>u3 : { value: number; } | { kind: "a"; value: string; } + +declare function two(x: { kind: "a"; sub: 1; value: T }): T; +>two : (x: { kind: "a"; sub: 1; value: T; }) => T +>x : { kind: "a"; sub: 1; value: T; } +>kind : "a" +>sub : 1 +>value : T + +const r6 = two(u4); +>r6 : string +>two(u4) : string +>two : (x: { kind: "a"; sub: 1; value: T; }) => T +>u4 : { kind: "a"; sub: 2; value: string; } | { kind: "b"; sub: 1; value: number; } + +declare function twoReversed(x: { sub: 1; kind: "a"; value: T }): T; +>twoReversed : (x: { sub: 1; kind: "a"; value: T; }) => T +>x : { sub: 1; kind: "a"; value: T; } +>sub : 1 +>kind : "a" +>value : T + +const r6Reversed = twoReversed(u4); +>r6Reversed : number +>twoReversed(u4) : number +>twoReversed : (x: { sub: 1; kind: "a"; value: T; }) => T +>u4 : { kind: "a"; sub: 2; value: string; } | { kind: "b"; sub: 1; value: number; } + +declare function enumTag(x: { kind: K.A; value: T }): T; +>enumTag : (x: { kind: K.A; value: T; }) => T +>x : { kind: K.A; value: T; } +>kind : K.A +>K : any +>value : T + +const r7 = enumTag(u5); +>r7 : string +>enumTag(u5) : string +>enumTag : (x: { kind: K.A; value: T; }) => T +>u5 : { kind: K.B; value: number; } | { kind: K.A; value: string; } + +declare function boolTag(x: { ok: boolean; value: T }): T; +>boolTag : (x: { ok: boolean; value: T; }) => T +>x : { ok: boolean; value: T; } +>ok : boolean +>value : T + +const r8 = boolTag(u6); +>r8 : number +>boolTag(u6) : number +>boolTag : (x: { ok: boolean; value: T; }) => T +>u6 : Err | Ok + +declare function wrap(value: T): { result: Ok }; +>wrap : (value: T) => { result: Ok; } +>value : T +>result : Ok + +export function nested(): { result: ErrShape | OkShape } { return wrap([]); } +>nested : () => { result: ErrShape | OkShape; } +>result : ErrShape | OkShape +>wrap([]) : { result: Ok<[]>; } +>wrap : (value: T) => { result: Ok; } +>[] : [] + +declare function success(value: T): Success; +>success : (value: T) => Success +>value : T + +export function withStringTag(): Success | Failure { +>withStringTag : () => Success | Failure + + return success([]); +>success([]) : Success<[]> +>success : (value: T) => Success +>[] : [] +} + +declare function accepted(value: T): Accepted; +>accepted : (value: T) => Accepted +>value : T + +export function withNumberTag(): Accepted | Rejected { +>withNumberTag : () => Accepted | Rejected + + return accepted([]); +>accepted([]) : Accepted<[]> +>accepted : (value: T) => Accepted +>[] : [] +} + +declare function unmatched(): { kind: "other"; value: T }; +>unmatched : () => { kind: "other"; value: T; } +>kind : "other" +>value : T + +export function withUnmatchedTag(): Success | Failure { +>withUnmatchedTag : () => Success | Failure + + return unmatched(); +>unmatched() : { kind: "other"; value: string[] | number[]; } +>unmatched : () => { kind: "other"; value: T; } +} + +declare function optionalOk(value: T): OptionalOk; +>optionalOk : (value: T) => OptionalOk +>value : T + +export function optionalTarget(): OptionalOk | Err { +>optionalTarget : () => OptionalOk | Err + + return optionalOk([]); +>optionalOk([]) : OptionalOk<[]> +>optionalOk : (value: T) => OptionalOk +>[] : [] +} + +export function bothOptional(): OptionalOk | MaybeErr { +>bothOptional : () => OptionalOk | MaybeErr + + return optionalOk([]); +>optionalOk([]) : OptionalOk +>optionalOk : (value: T) => OptionalOk +>[] : [] +} + +export function missingSourceTag(): OptionalOk | { value: string } { +>missingSourceTag : () => OptionalOk | { value: string; } +>value : string + + return optionalOk([]); +>optionalOk([]) : OptionalOk<[]> +>optionalOk : (value: T) => OptionalOk +>[] : [] +} + +export function undefinedSource(): OptionalOk | AlwaysUndefinedErr { +>undefinedSource : () => OptionalOk | AlwaysUndefinedErr + + return optionalOk([]); +>optionalOk([]) : OptionalOk +>optionalOk : (value: T) => OptionalOk +>[] : [] +} + +declare function explicitOptionalOk(value: T): ExplicitOptionalOk; +>explicitOptionalOk : (value: T) => ExplicitOptionalOk +>value : T + +export function explicitUndefined(): ExplicitOptionalOk | Err { +>explicitUndefined : () => ExplicitOptionalOk | Err + + return explicitOptionalOk([]); +>explicitOptionalOk([]) : ExplicitOptionalOk<[]> +>explicitOptionalOk : (value: T) => ExplicitOptionalOk +>[] : [] +} + +export function explicitUndefinedOverlap(): ExplicitOptionalOk | AlwaysUndefinedErr { +>explicitUndefinedOverlap : () => ExplicitOptionalOk | AlwaysUndefinedErr + + return explicitOptionalOk([]); +>explicitOptionalOk([]) : ExplicitOptionalOk +>explicitOptionalOk : (value: T) => ExplicitOptionalOk +>[] : [] +} + +declare function unionOk(value: T): UnionOk; +>unionOk : (value: T) => UnionOk +>value : T + +export function requiredUnionTag(): UnionOk | Err { +>requiredUnionTag : () => UnionOk | Err + + return unionOk([]); +>unionOk([]) : UnionOk<[]> +>unionOk : (value: T) => UnionOk +>[] : [] +} + +declare function undefinedOk(value: T): UndefinedOk; +>undefinedOk : (value: T) => UndefinedOk +>value : T + +export function undefinedTarget(): UndefinedOk | MaybeErr { +>undefinedTarget : () => UndefinedOk | MaybeErr + + return undefinedOk([]); +>undefinedOk([]) : UndefinedOk +>undefinedOk : (value: T) => UndefinedOk +>[] : [] +} + +declare function inferTwoArguments(first: Tagged, second: Tagged): [A, B]; +>inferTwoArguments : (first: Tagged, second: Tagged) => [A, B] +>first : Tagged +>second : Tagged + +const twoArguments = inferTwoArguments({ type: "a", value: 42 }, { type: "b", value: true }); +>twoArguments : [number, boolean] +>inferTwoArguments({ type: "a", value: 42 }, { type: "b", value: true }) : [number, boolean] +>inferTwoArguments : (first: Tagged, second: Tagged) => [A, B] +>{ type: "a", value: 42 } : { type: "a"; value: number; } +>type : "a" +>"a" : "a" +>value : number +>42 : 42 +>{ type: "b", value: true } : { type: "b"; value: true; } +>type : "b" +>"b" : "b" +>value : true +>true : true + +declare function inferInlineUnion(value: { type: "a"; value: A } | { type: "b"; value: B }): [A, B]; +>inferInlineUnion : (value: { type: "a"; value: A; } | { type: "b"; value: B; }) => [A, B] +>value : { type: "a"; value: A; } | { type: "b"; value: B; } +>type : "a" +>value : A +>type : "b" +>value : B + +const oneArgument = inferInlineUnion({ type: "a", value: 42 }); +>oneArgument : [number, unknown] +>inferInlineUnion({ type: "a", value: 42 }) : [number, unknown] +>inferInlineUnion : (value: { type: "a"; value: A; } | { type: "b"; value: B; }) => [A, B] +>{ type: "a", value: 42 } : { type: "a"; value: number; } +>type : "a" +>"a" : "a" +>value : number +>42 : 42 + +const unionArgument = inferInlineUnion(taggedSource); +>unionArgument : [string, number] +>inferInlineUnion(taggedSource) : [string, number] +>inferInlineUnion : (value: { type: "a"; value: A; } | { type: "b"; value: B; }) => [A, B] +>taggedSource : Tagged + +const explicitUnionArgument = inferInlineUnion(taggedSource); +>explicitUnionArgument : [string, number] +>inferInlineUnion(taggedSource) : [string, number] +>inferInlineUnion : (value: { type: "a"; value: A; } | { type: "b"; value: B; }) => [A, B] +>taggedSource : Tagged + +const reversedSourceUnion = inferInlineUnion(reversedTaggedSource); +>reversedSourceUnion : [string, number] +>inferInlineUnion(reversedTaggedSource) : [string, number] +>inferInlineUnion : (value: { type: "a"; value: A; } | { type: "b"; value: B; }) => [A, B] +>reversedTaggedSource : { type: "b"; value: number; } | { type: "a"; value: string; } + +const broadTargetUnion = inferInlineUnion(broadSourceTag); +>broadTargetUnion : [number, number] +>inferInlineUnion(broadSourceTag) : [number, number] +>inferInlineUnion : (value: { type: "a"; value: A; } | { type: "b"; value: B; }) => [A, B] +>broadSourceTag : { type: string; value: number; } + +const missingTargetUnion = inferInlineUnion(missingTag); +>missingTargetUnion : [number, number] +>inferInlineUnion(missingTag) : [number, number] +>inferInlineUnion : (value: { type: "a"; value: A; } | { type: "b"; value: B; }) => [A, B] +>missingTag : { value: number; } + +declare function inferUnionWithFallback(value: T | Tagged): [T, A, B]; +>inferUnionWithFallback : (value: T | Tagged) => [T, A, B] +>type : "a" | "b" +>value : T | Tagged + +const nakedTypeParameter = inferUnionWithFallback({ type: "a", value: 42 }); +>nakedTypeParameter : [{ type: "a"; value: number; }, number, unknown] +>inferUnionWithFallback({ type: "a", value: 42 }) : [{ type: "a"; value: number; }, number, unknown] +>inferUnionWithFallback : (value: T | Tagged) => [T, A, B] +>{ type: "a", value: 42 } : { type: "a"; value: number; } +>type : "a" +>"a" : "a" +>value : number +>42 : 42 + +declare function inferNoInferOverloads(first: Tagged>, second: Tagged): [A, B]; +>inferNoInferOverloads : { (first: Tagged>, second: Tagged): [A, B]; (first: Tagged, B_1>, second: Tagged): [A_1, B_1]; } +>first : Tagged> +>second : Tagged + +declare function inferNoInferOverloads(first: Tagged, B>, second: Tagged): [A, B]; +>inferNoInferOverloads : { (first: Tagged>, second: Tagged): [A_1, B_1]; (first: Tagged, B>, second: Tagged): [A, B]; } +>first : Tagged, B> +>second : Tagged + +const noInferArguments = inferNoInferOverloads({ type: "a", value: 42 }, { type: "b", value: true }); +>noInferArguments : [number, boolean] +>inferNoInferOverloads({ type: "a", value: 42 }, { type: "b", value: true }) : [number, boolean] +>inferNoInferOverloads : { (first: Tagged>, second: Tagged): [A, B]; (first: Tagged, B>, second: Tagged): [A, B]; } +>{ type: "a", value: 42 } : { type: "a"; value: number; } +>type : "a" +>"a" : "a" +>value : number +>42 : 42 +>{ type: "b", value: true } : { type: "b"; value: true; } +>type : "b" +>"b" : "b" +>value : true +>true : true + +const noInferReversedArguments = inferNoInferOverloads({ type: "b", value: true }, { type: "a", value: 42 }); +>noInferReversedArguments : [number, unknown] +>inferNoInferOverloads({ type: "b", value: true }, { type: "a", value: 42 }) : [number, unknown] +>inferNoInferOverloads : { (first: Tagged>, second: Tagged): [A, B]; (first: Tagged, B>, second: Tagged): [A, B]; } +>{ type: "b", value: true } : { type: "b"; value: boolean; } +>type : "b" +>"b" : "b" +>value : boolean +>true : true +>{ type: "a", value: 42 } : { type: "a"; value: number; } +>type : "a" +>"a" : "a" +>value : number +>42 : 42 + +declare function inferReversedUnion(value: { type: "b"; value: B } | { type: "a"; value: A }): [A, B]; +>inferReversedUnion : (value: { type: "b"; value: B; } | { type: "a"; value: A; }) => [A, B] +>value : { type: "b"; value: B; } | { type: "a"; value: A; } +>type : "b" +>value : B +>type : "a" +>value : A + +const reversedTargetUnion = inferReversedUnion(taggedSource); +>reversedTargetUnion : [string, number] +>inferReversedUnion(taggedSource) : [string, number] +>inferReversedUnion : (value: { type: "b"; value: B; } | { type: "a"; value: A; }) => [A, B] +>taggedSource : Tagged + +declare function inferTwoDiscriminants(value: { type: "a"; sub: 1; value: A } | { type: "b"; sub: 2; value: B }): [A, B]; +>inferTwoDiscriminants : (value: { type: "a"; sub: 1; value: A; } | { type: "b"; sub: 2; value: B; }) => [A, B] +>value : { type: "a"; sub: 1; value: A; } | { type: "b"; sub: 2; value: B; } +>type : "a" +>sub : 1 +>value : A +>type : "b" +>sub : 2 +>value : B + +const unmatchedTargetUnion = inferTwoDiscriminants({ type: "a", sub: 2, value: 42 }); +>unmatchedTargetUnion : [number, unknown] +>inferTwoDiscriminants({ type: "a", sub: 2, value: 42 }) : [number, unknown] +>inferTwoDiscriminants : (value: { type: "a"; sub: 1; value: A; } | { type: "b"; sub: 2; value: B; }) => [A, B] +>{ type: "a", sub: 2, value: 42 } : { type: "a"; sub: 2; value: number; } +>type : "a" +>"a" : "a" +>sub : 2 +>2 : 2 +>value : number +>42 : 42 + +const unmatchedTargetUnionReversedSource = inferTwoDiscriminants({ sub: 2, type: "a", value: 42 }); +>unmatchedTargetUnionReversedSource : [unknown, number] +>inferTwoDiscriminants({ sub: 2, type: "a", value: 42 }) : [unknown, number] +>inferTwoDiscriminants : (value: { type: "a"; sub: 1; value: A; } | { type: "b"; sub: 2; value: B; }) => [A, B] +>{ sub: 2, type: "a", value: 42 } : { sub: 2; type: "a"; value: number; } +>sub : 2 +>2 : 2 +>type : "a" +>"a" : "a" +>value : number +>42 : 42 + +declare function inferTwoDiscriminantsReversed(value: { sub: 1; type: "a"; value: A } | { sub: 2; type: "b"; value: B }): [A, B]; +>inferTwoDiscriminantsReversed : (value: { sub: 1; type: "a"; value: A; } | { sub: 2; type: "b"; value: B; }) => [A, B] +>value : { sub: 1; type: "a"; value: A; } | { sub: 2; type: "b"; value: B; } +>sub : 1 +>type : "a" +>value : A +>sub : 2 +>type : "b" +>value : B + +const unmatchedTargetUnionReversed = inferTwoDiscriminantsReversed({ type: "a", sub: 2, value: 42 }); +>unmatchedTargetUnionReversed : [number, unknown] +>inferTwoDiscriminantsReversed({ type: "a", sub: 2, value: 42 }) : [number, unknown] +>inferTwoDiscriminantsReversed : (value: { sub: 1; type: "a"; value: A; } | { sub: 2; type: "b"; value: B; }) => [A, B] +>{ type: "a", sub: 2, value: 42 } : { type: "a"; sub: 2; value: number; } +>type : "a" +>"a" : "a" +>sub : 2 +>2 : 2 +>value : number +>42 : 42 + +declare function inferOptionalUnion(value: { type?: "a"; value: A } | { type?: "b"; value: B }): [A, B]; +>inferOptionalUnion : (value: { type?: "a"; value: A; } | { type?: "b"; value: B; }) => [A, B] +>value : { type?: "a"; value: A; } | { type?: "b"; value: B; } +>type : "a" | undefined +>value : A +>type : "b" | undefined +>value : B + +const optionalTargetUnion = inferOptionalUnion(optionalTag); +>optionalTargetUnion : [string, string] +>inferOptionalUnion(optionalTag) : [string, string] +>inferOptionalUnion : (value: { type?: "a"; value: A; } | { type?: "b"; value: B; }) => [A, B] +>optionalTag : { type?: "a"; value: string; } + diff --git a/tsc/testdata/tests/cases/compiler/classExtendedDiscriminatedUnionInference.ts b/tsc/testdata/tests/cases/compiler/classExtendedDiscriminatedUnionInference.ts new file mode 100644 index 0000000000000..dca5c35994d2a --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/classExtendedDiscriminatedUnionInference.ts @@ -0,0 +1,16 @@ +declare class LocalController { + isLocal: true; + getProps(a: T, b: U): void; +} +declare class GlobalController { + isLocal: false; + // N.B.: Parameter type order is reversed + getProps(a: U, b: T): void; +} + +class FailWithTS42 extends LocalController<{ foo: any }, { bar: any }> { } +const p = new FailWithTS42(); + +declare function createEnhancer1(Wrapper: GlobalController | LocalController): [T, U]; +const q1 = createEnhancer1(p); +const q2 = createEnhancer1(p as LocalController<{ foo: any }, { bar: any }>); // structurally identical type to the above diff --git a/tsc/testdata/tests/cases/compiler/contextualTypingDiscriminantOverlap.ts b/tsc/testdata/tests/cases/compiler/contextualTypingDiscriminantOverlap.ts new file mode 100644 index 0000000000000..e49e01f799eb4 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/contextualTypingDiscriminantOverlap.ts @@ -0,0 +1,45 @@ +// @strict: true +// @exactOptionalPropertyTypes: false, true +// @noEmit: true + +type Handler = (value: T) => T; +type IndexedHandler = { + [key: string]: "b" | Handler<"b">; + value: Handler<"b">; +}; +type DeclaredOptionalHandler = { + [key: string]: "a" | "b" | undefined | Handler<"b">; + tag?: "a"; + value: Handler<"b">; +}; +type DeclaredRequiredHandler = { + [key: string]: "b" | Handler<"b">; + tag: "b"; + value: Handler<"b">; +}; + +const indexedOptional: + | { tag: "a"; value: Handler<"a"> } + | { tag?: "a"; value: Handler<"a"> } + | IndexedHandler = { + value: value => value, // error + }; + +const declaredOptional: + | { tag: "a"; value: Handler<"a"> } + | DeclaredOptionalHandler = { + value: value => value, + }; + +const declaredRequired: + | { tag: "a"; value: Handler<"a"> } + | DeclaredRequiredHandler = { + tag: "a", + value: value => value, + }; + +const indexedRequired: + | { tag: "a"; value: Handler<"a"> } + | IndexedHandler = { + value: value => value, // error + }; diff --git a/tsc/testdata/tests/cases/compiler/discriminatedUnionInferenceClassHierarchies.ts b/tsc/testdata/tests/cases/compiler/discriminatedUnionInferenceClassHierarchies.ts new file mode 100644 index 0000000000000..17db1906c376c --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/discriminatedUnionInferenceClassHierarchies.ts @@ -0,0 +1,68 @@ +// @strict: true +// @noEmit: true + +// The discriminant lives on the instance type behind a construct signature. +declare class GlobalController { + isLocal: false; + getProps(state: S, props: P): void; +} +declare class LocalController { + isLocal: true; + getProps(props: P, state: S): void; +} +interface GlobalControllerClass { + new (): GlobalController; +} +interface LocalControllerClass { + new (): LocalController; +} +declare function createEnhancer(Wrapper: GlobalControllerClass | LocalControllerClass): [P, S]; + +class Fail extends LocalController<{ baz: any }, { bar: any }> {} +const enhanced = createEnhancer(Fail); + +class WorkaroundUnusedMethod extends LocalController<{ baz: any }, { bar: any }> { + _unused() {} +} +const enhancedUnusedMethod = createEnhancer(WorkaroundUnusedMethod); + +class WorkaroundChangeSignature extends LocalController<{ baz: any }, { bar: any }> { + getProps(props: { baz: any }) {} +} +const enhancedChangedSignature = createEnhancer(WorkaroundChangeSignature); + +// Three type parameters with a default, as in the original report. +declare abstract class GlobalStoreController { + isLocal: false; + abstract getProps(storeState: SS, props: P, state: S): void; +} +interface GlobalStoreControllerClass { + new (): GlobalStoreController; +} +type ControllerClass = GlobalStoreControllerClass | LocalControllerClass; +declare function createStoreEnhancer(Wrapper: ControllerClass): [P, S, SS]; +const storeEnhanced = createStoreEnhancer(Fail); + +// Instances declared directly, through an alias, and through an extending interface. +interface Local { + isLocal: true; + a: T; + b: U; +} +interface NotLocal { + isLocal: false; + a: U; + b: T; +} +declare function callme(Wrapper: NotLocal | Local): [T, U]; + +declare const directDecl: Local; +const direct = callme(directDecl); + +type LocalStringNumberAlias = Local; +declare const typeAlias: LocalStringNumberAlias; +const alias = callme(typeAlias); + +interface LocalStringNumberInterface extends Local {} +declare const interfaceDecl: LocalStringNumberInterface; +const extended = callme(interfaceDecl); diff --git a/tsc/testdata/tests/cases/compiler/inferenceDiscriminantOverlap.ts b/tsc/testdata/tests/cases/compiler/inferenceDiscriminantOverlap.ts new file mode 100644 index 0000000000000..fcecbbb5d3e26 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/inferenceDiscriminantOverlap.ts @@ -0,0 +1,77 @@ +// @strict: true +// @exactOptionalPropertyTypes: false, true +// @noEmit: true + +declare const validOptionalSource: { tag: "a"; value: 1 } | { tag?: "a"; value: 2 }; +declare const mixedOptionalSource: { tag: "a"; value: 1 } | { tag?: "b"; value: 2 }; +declare const matchingOptionalSource: { tag: "a"; value: 1 } | { tag?: "a"; value: 2 } | { tag: "b"; value: 3 }; +declare const requiredMismatchSource: { tag: "a"; value: 1 } | { tag: "b"; value: 2 }; +declare const partiallyMatchingSource: { tag: "a" | "b"; value: 1 } | { tag: "b"; value: 2 }; +declare const undefinedRequiredSource: { tag: "a"; value: 1 } | { tag: undefined; value: 2 }; +declare const explicitUndefinedSource: { tag: "a"; value: 1 } | { tag: "b" | undefined; value: 2 }; +declare const optionalNeverSource: { tag: "a"; value: 1 } | { tag?: never; value: 2 }; + +declare const indexedSource: + | { tag: "a"; value: "a" } + | { tag?: "a"; value: "a" } + | { [key: string]: "b"; value: "b" }; +declare const requiredPropertySource: + | { tag: "a"; value: "a" } + | { [key: string]: "b"; tag: "b"; value: "b" }; +declare const optionalPropertySource: + | { tag: "a"; value: "a" } + | { [key: string]: "a" | "b" | undefined; tag?: "a"; value: "b" }; + +declare function inferOptionalSource(value: { tag?: "a"; value: T }): T; +const validOptional = inferOptionalSource(validOptionalSource); +const mixedOptional = inferOptionalSource(mixedOptionalSource); +const matchingOptional = inferOptionalSource(matchingOptionalSource); +const requiredMismatch = inferOptionalSource(requiredMismatchSource); +const requiredUndefined = inferOptionalSource(undefinedRequiredSource); +const explicitUndefined = inferOptionalSource(explicitUndefinedSource); +const optionalNever = inferOptionalSource(optionalNeverSource); +const indexedOptional = inferOptionalSource(indexedSource); // error +const declaredOptional = inferOptionalSource(optionalPropertySource); // error +const declaredRequired = inferOptionalSource(requiredPropertySource); // error + +declare function inferRequiredSource(value: { tag: "a"; value: T }): T; +const partiallyMatching = inferRequiredSource(partiallyMatchingSource); +const indexedRequired = inferRequiredSource(indexedSource); // error + +declare function makeOptional(): { tag?: "a"; value: T }; +export function optionalContext(): { tag: "a"; value: 1 } | { tag?: "b"; value: 2 } { + return makeOptional(); +} + +declare function inferOptionalTargets(value: { tag: "a"; value: A } | { tag?: "b"; value: B }): [A, B]; +declare const optionalInput: { tag?: "a"; value: 42 }; +declare const optionalNeverInput: { tag?: never; value: 42 }; +const optionalTargetInference = inferOptionalTargets(optionalInput); +const optionalNeverTargetInference = inferOptionalTargets(optionalNeverInput); + +// Return type inference runs with the contextual type as the source and the declared +// return type as the target, so assignability has to hold the other way around. +declare function makeTagged(value: T): { kind: "a"; value: T }; +declare function makeOptionalTagged(value: T): { kind?: "a"; value: T }; +declare function makeUnionTagged(value: T): { kind: "a" | undefined; value: T }; + +export function broadContext(): { kind: string; value: string[] } | { kind: "a"; value: number } { + return makeTagged([]); +} +export function partialTagContext(): { kind: "a" | "b"; value: string[] } | { kind: "a"; value: number } { + return makeTagged([]); +} +export function unionTagContext(): { kind?: "a"; value: string[] } | { kind: "a"; value: number } { + return makeUnionTagged([]); +} +export function indexedContext(): + | { [key: string]: string | string[]; value: string[] } + | { kind: "a"; value: number } + | { kind: "b"; value: boolean } { + return makeOptionalTagged([]); +} + +declare function makeEither(a: A, b: B): { kind: "a"; value: A } | { kind: "b"; value: B }; +export function eitherContext(): { kind: "a"; value: string[] } | { kind: "b"; value: number[] } { + return makeEither([], []); +} diff --git a/tsc/testdata/tests/cases/compiler/inferenceDiscriminatedUnions1.ts b/tsc/testdata/tests/cases/compiler/inferenceDiscriminatedUnions1.ts new file mode 100644 index 0000000000000..f12dd66c7812d --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/inferenceDiscriminatedUnions1.ts @@ -0,0 +1,157 @@ +// @strict: true +// @exactOptionalPropertyTypes: false, true +// @noEmit: true + +type Ok = { ok: true; value: T }; +type Err = { ok: false; value: E }; +type ErrShape = { ok: false; value: string }; +type OkShape = { ok: true; value: string[] }; +enum K { A, B } +type Success = { kind: "success"; value: T }; +type Failure = { kind: "failure"; value: E }; +type Accepted = { kind: 1; value: T }; +type Rejected = { kind: 0; value: E }; +type OptionalOk = { ok?: true; value: T }; +type MaybeErr = { ok?: false; value: E }; +type ExplicitOptionalOk = { ok?: true | undefined; value: T }; +type UnionOk = { ok: true | undefined; value: T }; +type AlwaysUndefinedErr = { ok: undefined; value: E }; +type UndefinedOk = { ok: undefined; value: T }; +type Tagged = { type: "a"; value: A } | { type: "b"; value: B }; + +declare const u1: { kind: "b"; value: number } | { kind: "a"; value: string }; +declare const u2: { kind: string; value: number } | { kind: "a"; value: string }; +declare const broadTag: { kind: number; value: number } | { kind: "a"; value: string }; +declare const u3: { value: number } | { kind: "a"; value: string }; +declare const u4: { kind: "a"; sub: 2; value: string } | { kind: "b"; sub: 1; value: number }; +declare const u5: { kind: K.B; value: number } | { kind: K.A; value: string }; +declare const u6: Err | Ok; +declare const taggedSource: Tagged; +declare const reversedTaggedSource: { type: "b"; value: number } | { type: "a"; value: string }; +declare const broadSourceTag: { type: string; value: number }; +declare const missingTag: { value: number }; +declare const optionalTag: { type?: "a"; value: string }; + +declare function ok(value: T): Ok; +export function aliasTarget(): ErrShape | OkShape { return ok([]); } + +export function f(): Ok | Err { + return ok([]); +} + +export function optionalSource(): Ok | MaybeErr { + return ok([]); +} + +declare function okInline(value: T): { ok: true; value: T }; +export function inlineTarget(): ErrShape | OkShape { return okInline([]); } + +export function inlineTargetReversed(): OkShape | ErrShape { return okInline([]); } + +declare function on(handler: (e: { kind: "a"; value: T }) => void): T; +const r1 = on((e: { kind: "a"; value: string } | { kind: "b"; value: number }) => {}); +const r2 = on((e: { kind: "b"; value: number } | { kind: "a"; value: string }) => {}); + +declare function pick(x: { kind: "a"; value: T }): T; +const r3 = pick(u1); +const r4 = pick(u2); +const broadResult = pick(broadTag); +const r5 = pick(u3); + +declare function two(x: { kind: "a"; sub: 1; value: T }): T; +const r6 = two(u4); + +declare function twoReversed(x: { sub: 1; kind: "a"; value: T }): T; +const r6Reversed = twoReversed(u4); + +declare function enumTag(x: { kind: K.A; value: T }): T; +const r7 = enumTag(u5); + +declare function boolTag(x: { ok: boolean; value: T }): T; +const r8 = boolTag(u6); + +declare function wrap(value: T): { result: Ok }; +export function nested(): { result: ErrShape | OkShape } { return wrap([]); } + +declare function success(value: T): Success; +export function withStringTag(): Success | Failure { + return success([]); +} + +declare function accepted(value: T): Accepted; +export function withNumberTag(): Accepted | Rejected { + return accepted([]); +} + +declare function unmatched(): { kind: "other"; value: T }; +export function withUnmatchedTag(): Success | Failure { + return unmatched(); +} + +declare function optionalOk(value: T): OptionalOk; +export function optionalTarget(): OptionalOk | Err { + return optionalOk([]); +} + +export function bothOptional(): OptionalOk | MaybeErr { + return optionalOk([]); +} + +export function missingSourceTag(): OptionalOk | { value: string } { + return optionalOk([]); +} + +export function undefinedSource(): OptionalOk | AlwaysUndefinedErr { + return optionalOk([]); +} + +declare function explicitOptionalOk(value: T): ExplicitOptionalOk; +export function explicitUndefined(): ExplicitOptionalOk | Err { + return explicitOptionalOk([]); +} + +export function explicitUndefinedOverlap(): ExplicitOptionalOk | AlwaysUndefinedErr { + return explicitOptionalOk([]); +} + +declare function unionOk(value: T): UnionOk; +export function requiredUnionTag(): UnionOk | Err { + return unionOk([]); +} + +declare function undefinedOk(value: T): UndefinedOk; +export function undefinedTarget(): UndefinedOk | MaybeErr { + return undefinedOk([]); +} + +declare function inferTwoArguments(first: Tagged, second: Tagged): [A, B]; +const twoArguments = inferTwoArguments({ type: "a", value: 42 }, { type: "b", value: true }); + +declare function inferInlineUnion(value: { type: "a"; value: A } | { type: "b"; value: B }): [A, B]; +const oneArgument = inferInlineUnion({ type: "a", value: 42 }); +const unionArgument = inferInlineUnion(taggedSource); +const explicitUnionArgument = inferInlineUnion(taggedSource); +const reversedSourceUnion = inferInlineUnion(reversedTaggedSource); +const broadTargetUnion = inferInlineUnion(broadSourceTag); +const missingTargetUnion = inferInlineUnion(missingTag); + +declare function inferUnionWithFallback(value: T | Tagged): [T, A, B]; +const nakedTypeParameter = inferUnionWithFallback({ type: "a", value: 42 }); + +declare function inferNoInferOverloads(first: Tagged>, second: Tagged): [A, B]; +declare function inferNoInferOverloads(first: Tagged, B>, second: Tagged): [A, B]; +const noInferArguments = inferNoInferOverloads({ type: "a", value: 42 }, { type: "b", value: true }); +const noInferReversedArguments = inferNoInferOverloads({ type: "b", value: true }, { type: "a", value: 42 }); + +declare function inferReversedUnion(value: { type: "b"; value: B } | { type: "a"; value: A }): [A, B]; +const reversedTargetUnion = inferReversedUnion(taggedSource); + +declare function inferTwoDiscriminants(value: { type: "a"; sub: 1; value: A } | { type: "b"; sub: 2; value: B }): [A, B]; +const unmatchedTargetUnion = inferTwoDiscriminants({ type: "a", sub: 2, value: 42 }); +const unmatchedTargetUnionReversedSource = inferTwoDiscriminants({ sub: 2, type: "a", value: 42 }); + +declare function inferTwoDiscriminantsReversed(value: { sub: 1; type: "a"; value: A } | { sub: 2; type: "b"; value: B }): [A, B]; +const unmatchedTargetUnionReversed = inferTwoDiscriminantsReversed({ type: "a", sub: 2, value: 42 }); + +declare function inferOptionalUnion(value: { type?: "a"; value: A } | { type?: "b"; value: B }): [A, B]; +const optionalTargetUnion = inferOptionalUnion(optionalTag);