diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b439b7fd9c579..31be8c4d4b3c1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1333,6 +1333,7 @@ export const enum CheckMode { // e.g. in `const { a, ...rest } = foo`, when checking the type of `foo` to determine the type of `rest`, // we need to preserve generic types instead of substituting them for constraints TypeOnly = 1 << 6, // Called from getTypeOfExpression, diagnostics may be omitted + SatisfiesOutput = 1 << 7, // Used to get output type of a satisfies expression unaffected by narrowable types for references, used in combination with `ContextFlags.SkipSatisfies` } /** @internal */ @@ -29800,17 +29801,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { !!(type.flags & TypeFlags.Instantiable && !maybeTypeOfKind(getBaseConstraintOrType(type), TypeFlags.Nullable)); } - function hasContextualTypeWithNoGenericTypes(node: Node, checkMode: CheckMode | undefined) { + function hasContextualTypeWithNoGenericTypes(node: Node, checkMode = CheckMode.Normal) { // Computing the contextual type for a child of a JSX element involves resolving the type of the // element's tag name, so we exclude that here to avoid circularities. // If check mode has `CheckMode.RestBindingElement`, we skip binding pattern contextual types, // as we want the type of a rest element to be generic when possible. const contextualType = (isIdentifier(node) || isPropertyAccessExpression(node) || isElementAccessExpression(node)) && !((isJsxOpeningElement(node.parent) || isJsxSelfClosingElement(node.parent)) && node.parent.tagName === node) && - (checkMode && checkMode & CheckMode.RestBindingElement ? - getContextualType(node, ContextFlags.SkipBindingPatterns) - : getContextualType(node, /*contextFlags*/ undefined)); - return contextualType && !isGenericType(contextualType); + getContextualType(node, (checkMode & CheckMode.RestBindingElement ? ContextFlags.SkipBindingPatterns : 0) | (checkMode & CheckMode.SatisfiesOutput ? ContextFlags.SkipSatisfies : 0)); + return contextualType && !(contextualType.flags & TypeFlags.Any) && !isGenericType(contextualType); } function getNarrowableTypeForReference(type: Type, reference: Node, checkMode?: CheckMode, forReturnTypeNarrowing?: boolean) { @@ -32190,6 +32189,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case SyntaxKind.NonNullExpression: return getContextualType(parent as NonNullExpression, contextFlags); case SyntaxKind.SatisfiesExpression: + if (contextFlags && contextFlags & ContextFlags.SkipSatisfies) { + return getContextualType(parent as SatisfiesExpression, contextFlags); + } return getTypeFromTypeNode((parent as SatisfiesExpression).type); case SyntaxKind.ExportAssignment: return tryGetTypeFromEffectiveTypeNode(parent as ExportAssignment); @@ -37573,7 +37575,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return checkSatisfiesExpressionWorker(node.expression, node.type); } - function checkSatisfiesExpressionWorker(expression: Expression, target: TypeNode, checkMode?: CheckMode) { + function checkSatisfiesExpressionWorker(expression: Expression, target: TypeNode, checkMode = CheckMode.Normal) { const exprType = checkExpression(expression, checkMode); const targetType = getTypeFromTypeNode(target); if (isErrorType(targetType)) { @@ -37581,7 +37583,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } const errorNode = findAncestor(target.parent, n => n.kind === SyntaxKind.SatisfiesExpression || n.kind === SyntaxKind.JSDocSatisfiesTag); checkTypeAssignableToAndOptionallyElaborate(exprType, targetType, errorNode, expression, Diagnostics.Type_0_does_not_satisfy_the_expected_type_1); - return exprType; + return checkExpression(expression, checkMode | CheckMode.SatisfiesOutput); } function checkMetaProperty(node: MetaProperty): Type { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 46ff57009e7fa..e6870c21be1c6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5462,11 +5462,12 @@ export const enum IntersectionFlags { // dprint-ignore /** @internal */ export const enum ContextFlags { - None = 0, - Signature = 1 << 0, // Obtaining contextual signature - NoConstraints = 1 << 1, // Don't obtain type variable constraints - Completions = 1 << 2, // Ignore inference to current node and parent nodes out to the containing call for completions + None = 0, + Signature = 1 << 0, // Obtaining contextual signature + NoConstraints = 1 << 1, // Don't obtain type variable constraints + Completions = 1 << 2, // Ignore inference to current node and parent nodes out to the containing call for completions SkipBindingPatterns = 1 << 3, // Ignore contextual types applied by binding patterns + SkipSatisfies = 1 << 4, // Ignore contextual types applied by `satisfies` types } // NOTE: If modifying this enum, must modify `TypeFormatFlags` too! diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 107f954def412..36d2cbceb8b6e 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -721,7 +721,8 @@ function getArgumentTypesAndTypeParameters(checker: TypeChecker, importAdder: Im } argumentTypeNodes.push(argumentTypeNode); - const argumentTypeParameter = getFirstTypeParameterName(instanceType); + const type = instanceType.isIndexType() ? instanceType.type : instanceType; + const argumentTypeParameter = getFirstTypeParameterName(type); // If the instance type is a type parameter with a constraint (other than an anonymous object), // remember that constraint for when we create the new type parameter @@ -732,12 +733,12 @@ function getArgumentTypesAndTypeParameters(checker: TypeChecker, importAdder: Im // function added(value: T) { ... } // We instead want to output: // function added(value: T) { ... } - const instanceTypeConstraint = instanceType.isTypeParameter() && instanceType.constraint && !isAnonymousObjectConstraintType(instanceType.constraint) - ? typeToAutoImportableTypeNode(checker, importAdder, instanceType.constraint, contextNode, scriptTarget, flags, internalFlags, tracker) + const typeConstraint = type.isTypeParameter() && type.constraint && !isAnonymousObjectConstraintType(type.constraint) + ? typeToAutoImportableTypeNode(checker, importAdder, type.constraint, contextNode, scriptTarget, flags, internalFlags, tracker) : undefined; if (argumentTypeParameter) { - argumentTypeParameters.set(argumentTypeParameter, { argumentType: instanceType, constraint: instanceTypeConstraint }); + argumentTypeParameters.set(argumentTypeParameter, { argumentType: type, constraint: typeConstraint }); } } diff --git a/tests/baselines/reference/controlFlowGenericTypes.types b/tests/baselines/reference/controlFlowGenericTypes.types index 34aaf80709138..40af379e90637 100644 --- a/tests/baselines/reference/controlFlowGenericTypes.types +++ b/tests/baselines/reference/controlFlowGenericTypes.types @@ -160,8 +160,8 @@ function g1 | undefined>(x: T) { > : ^^^^^^^ >isBox : (x: any) => x is Box > : ^ ^^ ^^^^^ ->x : Box | undefined -> : ^^^^^^^^^^^^^^^^^^ +>x : T +> : ^ unbox(x); >unbox(x) : T @@ -212,8 +212,8 @@ function g3 | undefined>(x: T) { > : ^^^^^^^ >isBox : (x: any) => x is Box > : ^ ^^ ^^^^^ ->x : Box | undefined -> : ^^^^^^^^^^^^^^^^^^ +>x : T +> : ^ unbox(x); // Error >unbox(x) : T diff --git a/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.symbols b/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.symbols new file mode 100644 index 0000000000000..37402186edcfd --- /dev/null +++ b/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.symbols @@ -0,0 +1,41 @@ +//// [tests/cases/compiler/controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts] //// + +=== controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts === +const foo_autoType = (bar: T) => { +>foo_autoType : Symbol(foo_autoType, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 0, 5)) +>T : Symbol(T, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 0, 22)) +>bar : Symbol(bar, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 0, 39)) +>T : Symbol(T, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 0, 22)) + + let test1; +>test1 : Symbol(test1, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 1, 5)) + + test1 = bar; +>test1 : Symbol(test1, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 1, 5)) +>bar : Symbol(bar, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 0, 39)) + + return test1; +>test1 : Symbol(test1, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 1, 5)) + +}; + +const foo_autoArrayType = (bar: T) => { +>foo_autoArrayType : Symbol(foo_autoArrayType, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 6, 5)) +>T : Symbol(T, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 6, 27)) +>bar : Symbol(bar, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 6, 44)) +>T : Symbol(T, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 6, 27)) + + let test1 = []; +>test1 : Symbol(test1, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 7, 5)) + + test1.push(bar); +>test1.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>test1 : Symbol(test1, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 7, 5)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>bar : Symbol(bar, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 6, 44)) + + return test1; +>test1 : Symbol(test1, Decl(controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts, 7, 5)) + +}; + diff --git a/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.types b/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.types new file mode 100644 index 0000000000000..1786ca409a8f9 --- /dev/null +++ b/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.types @@ -0,0 +1,59 @@ +//// [tests/cases/compiler/controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts] //// + +=== controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts === +const foo_autoType = (bar: T) => { +>foo_autoType : (bar: T) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^ +>(bar: T) => { let test1; test1 = bar; return test1;} : (bar: T) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^ +>bar : T +> : ^ + + let test1; +>test1 : any + + test1 = bar; +>test1 = bar : T +> : ^ +>test1 : any +>bar : T +> : ^ + + return test1; +>test1 : T +> : ^ + +}; + +const foo_autoArrayType = (bar: T) => { +>foo_autoArrayType : (bar: T) => T[] +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^ +>(bar: T) => { let test1 = []; test1.push(bar); return test1;} : (bar: T) => T[] +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^ +>bar : T +> : ^ + + let test1 = []; +>test1 : any[] +> : ^^^^^ +>[] : never[] +> : ^^^^^^^ + + test1.push(bar); +>test1.push(bar) : number +> : ^^^^^^ +>test1.push : (...items: any[]) => number +> : ^^^^ ^^^^^^^^^^^^ +>test1 : any[] +> : ^^^^^ +>push : (...items: any[]) => number +> : ^^^^ ^^^^^^^^^^^^ +>bar : T +> : ^ + + return test1; +>test1 : T[] +> : ^^^ + +}; + diff --git a/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithSatisfies1.errors.txt b/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithSatisfies1.errors.txt new file mode 100644 index 0000000000000..4cd1c9c6f8d34 --- /dev/null +++ b/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithSatisfies1.errors.txt @@ -0,0 +1,75 @@ +controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts(50,3): error TS2322: Type '{ readonly table: T; readonly id: "foo"; }' is not assignable to type 'RecordPointer'. + Type '{ readonly table: T; readonly id: "foo"; }' is not assignable to type '{ id: string; table: "space"; }'. + Types of property 'table' are incompatible. + Type 'T' is not assignable to type '"space"'. + Type 'Table' is not assignable to type '"space"'. + Type '"block"' is not assignable to type '"space"'. + + +==== controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts (1 errors) ==== + // https://github.com/microsoft/TypeScript/issues/52394 + + const foo52394 = (bar: T) => { + const a = bar satisfies any; + return a; + }; + + type MyType52394 = { + a: string; + b: "a" | "b" | "c" | "d" | "e"; + }; + const foo2_52394 = (bar: T) => + ({ + a: bar, + b: bar, + }) satisfies MyType52394; + + type BoxState = "open" | "closed"; + + type Box = { + boxState: BoxState; + boxedObject: unknown; + }; + + function boxFactorySafe( + boxState: BS, + boxedObject: unknown, + ) { + return { + boxState, + boxedObject, + } as const satisfies Box; + } + + const safeBoxedObject = boxFactorySafe("open", "some value"); + + // https://github.com/microsoft/TypeScript/issues/60698 + + type Table = "block" | "collection" | "space"; + + type RecordPointer = { + [T_ in T]: { + id: string; + table: T_; + }; + }[T]; + + function g(t: T): RecordPointer
{ + const x = { table: t, id: "foo" } as const satisfies RecordPointer
; + return x; // error + ~~~~~~ +!!! error TS2322: Type '{ readonly table: T; readonly id: "foo"; }' is not assignable to type 'RecordPointer
'. +!!! error TS2322: Type '{ readonly table: T; readonly id: "foo"; }' is not assignable to type '{ id: string; table: "space"; }'. +!!! error TS2322: Types of property 'table' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type '"space"'. +!!! error TS2322: Type 'Table' is not assignable to type '"space"'. +!!! error TS2322: Type '"block"' is not assignable to type '"space"'. + } + + export function bounceAndTakeIfA(value: AB) { + if (value === "A") { + const temp = value satisfies "A" + const takeA: "A" = value satisfies "A"; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithSatisfies1.symbols b/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithSatisfies1.symbols new file mode 100644 index 0000000000000..e71bd2dbd5eca --- /dev/null +++ b/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithSatisfies1.symbols @@ -0,0 +1,158 @@ +//// [tests/cases/compiler/controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts] //// + +=== controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts === +// https://github.com/microsoft/TypeScript/issues/52394 + +const foo52394 = (bar: T) => { +>foo52394 : Symbol(foo52394, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 2, 5)) +>T : Symbol(T, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 2, 18)) +>bar : Symbol(bar, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 2, 35)) +>T : Symbol(T, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 2, 18)) + + const a = bar satisfies any; +>a : Symbol(a, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 3, 7)) +>bar : Symbol(bar, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 2, 35)) + + return a; +>a : Symbol(a, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 3, 7)) + +}; + +type MyType52394 = { +>MyType52394 : Symbol(MyType52394, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 5, 2)) + + a: string; +>a : Symbol(a, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 7, 20)) + + b: "a" | "b" | "c" | "d" | "e"; +>b : Symbol(b, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 8, 12)) + +}; +const foo2_52394 = (bar: T) => +>foo2_52394 : Symbol(foo2_52394, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 11, 5)) +>T : Symbol(T, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 11, 20)) +>bar : Symbol(bar, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 11, 47)) +>T : Symbol(T, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 11, 20)) + + ({ + a: bar, +>a : Symbol(a, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 12, 4)) +>bar : Symbol(bar, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 11, 47)) + + b: bar, +>b : Symbol(b, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 13, 11)) +>bar : Symbol(bar, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 11, 47)) + + }) satisfies MyType52394; +>MyType52394 : Symbol(MyType52394, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 5, 2)) + +type BoxState = "open" | "closed"; +>BoxState : Symbol(BoxState, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 15, 27)) + +type Box = { +>Box : Symbol(Box, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 17, 34)) + + boxState: BoxState; +>boxState : Symbol(boxState, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 19, 12)) +>BoxState : Symbol(BoxState, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 15, 27)) + + boxedObject: unknown; +>boxedObject : Symbol(boxedObject, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 20, 21)) + +}; + +function boxFactorySafe( +>boxFactorySafe : Symbol(boxFactorySafe, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 22, 2)) +>BS : Symbol(BS, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 24, 24)) +>BoxState : Symbol(BoxState, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 15, 27)) + + boxState: BS, +>boxState : Symbol(boxState, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 24, 45)) +>BS : Symbol(BS, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 24, 24)) + + boxedObject: unknown, +>boxedObject : Symbol(boxedObject, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 25, 15)) + +) { + return { + boxState, +>boxState : Symbol(boxState, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 28, 10)) + + boxedObject, +>boxedObject : Symbol(boxedObject, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 29, 13)) + + } as const satisfies Box; +>const : Symbol(const) +>Box : Symbol(Box, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 17, 34)) +} + +const safeBoxedObject = boxFactorySafe("open", "some value"); +>safeBoxedObject : Symbol(safeBoxedObject, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 34, 5)) +>boxFactorySafe : Symbol(boxFactorySafe, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 22, 2)) + +// https://github.com/microsoft/TypeScript/issues/60698 + +type Table = "block" | "collection" | "space"; +>Table : Symbol(Table, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 34, 61)) + +type RecordPointer = { +>RecordPointer : Symbol(RecordPointer, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 38, 46)) +>T : Symbol(T, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 40, 19)) +>Table : Symbol(Table, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 34, 61)) + + [T_ in T]: { +>T_ : Symbol(T_, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 41, 3)) +>T : Symbol(T, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 40, 19)) + + id: string; +>id : Symbol(id, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 41, 14)) + + table: T_; +>table : Symbol(table, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 42, 15)) +>T_ : Symbol(T_, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 41, 3)) + + }; +}[T]; +>T : Symbol(T, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 40, 19)) + +function g(t: T): RecordPointer
{ +>g : Symbol(g, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 45, 5)) +>T : Symbol(T, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 47, 11)) +>Table : Symbol(Table, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 34, 61)) +>t : Symbol(t, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 47, 28)) +>T : Symbol(T, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 47, 11)) +>RecordPointer : Symbol(RecordPointer, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 38, 46)) +>Table : Symbol(Table, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 34, 61)) + + const x = { table: t, id: "foo" } as const satisfies RecordPointer
; +>x : Symbol(x, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 48, 7)) +>table : Symbol(table, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 48, 13)) +>t : Symbol(t, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 47, 28)) +>id : Symbol(id, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 48, 23)) +>const : Symbol(const) +>RecordPointer : Symbol(RecordPointer, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 38, 46)) +>Table : Symbol(Table, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 34, 61)) + + return x; // error +>x : Symbol(x, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 48, 7)) +} + +export function bounceAndTakeIfA(value: AB) { +>bounceAndTakeIfA : Symbol(bounceAndTakeIfA, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 50, 1)) +>AB : Symbol(AB, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 52, 33)) +>value : Symbol(value, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 52, 55)) +>AB : Symbol(AB, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 52, 33)) + + if (value === "A") { +>value : Symbol(value, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 52, 55)) + + const temp = value satisfies "A" +>temp : Symbol(temp, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 54, 9)) +>value : Symbol(value, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 52, 55)) + + const takeA: "A" = value satisfies "A"; +>takeA : Symbol(takeA, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 55, 9)) +>value : Symbol(value, Decl(controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts, 52, 55)) + } +} + diff --git a/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithSatisfies1.types b/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithSatisfies1.types new file mode 100644 index 0000000000000..14772ba95ff5a --- /dev/null +++ b/tests/baselines/reference/controlFlowGenericTypesNarrowableReferencesWithSatisfies1.types @@ -0,0 +1,215 @@ +//// [tests/cases/compiler/controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts] //// + +=== controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts === +// https://github.com/microsoft/TypeScript/issues/52394 + +const foo52394 = (bar: T) => { +>foo52394 : (bar: T) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^ +>(bar: T) => { const a = bar satisfies any; return a;} : (bar: T) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^ +>bar : T +> : ^ + + const a = bar satisfies any; +>a : T +> : ^ +>bar satisfies any : T +> : ^ +>bar : T +> : ^ + + return a; +>a : T +> : ^ + +}; + +type MyType52394 = { +>MyType52394 : MyType52394 +> : ^^^^^^^^^^^ + + a: string; +>a : string +> : ^^^^^^ + + b: "a" | "b" | "c" | "d" | "e"; +>b : "a" | "b" | "c" | "d" | "e" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +}; +const foo2_52394 = (bar: T) => +>foo2_52394 : (bar: T) => { a: T; b: T; } +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^ +>(bar: T) => ({ a: bar, b: bar, }) satisfies MyType52394 : (bar: T) => { a: T; b: T; } +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^ +>bar : T +> : ^ + + ({ +>({ a: bar, b: bar, }) satisfies MyType52394 : { a: T; b: T; } +> : ^^^^^^^^^^^^^^^ +>({ a: bar, b: bar, }) : { a: "a" | "b" | "c"; b: "a" | "b" | "c"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ a: bar, b: bar, } : { a: "a" | "b" | "c"; b: "a" | "b" | "c"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + a: bar, +>a : "a" | "b" | "c" +> : ^^^^^^^^^^^^^^^ +>bar : "a" | "b" | "c" +> : ^^^^^^^^^^^^^^^ + + b: bar, +>b : "a" | "b" | "c" +> : ^^^^^^^^^^^^^^^ +>bar : "a" | "b" | "c" +> : ^^^^^^^^^^^^^^^ + + }) satisfies MyType52394; + +type BoxState = "open" | "closed"; +>BoxState : BoxState +> : ^^^^^^^^ + +type Box = { +>Box : Box +> : ^^^ + + boxState: BoxState; +>boxState : BoxState +> : ^^^^^^^^ + + boxedObject: unknown; +>boxedObject : unknown +> : ^^^^^^^ + +}; + +function boxFactorySafe( +>boxFactorySafe : (boxState: BS, boxedObject: unknown) => { readonly boxState: BS; readonly boxedObject: unknown; } +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + boxState: BS, +>boxState : BS +> : ^^ + + boxedObject: unknown, +>boxedObject : unknown +> : ^^^^^^^ + +) { + return { +>{ boxState, boxedObject, } as const satisfies Box : { readonly boxState: BS; readonly boxedObject: unknown; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ boxState, boxedObject, } as const : { readonly boxState: BoxState; readonly boxedObject: unknown; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ boxState, boxedObject, } : { readonly boxState: BoxState; readonly boxedObject: unknown; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + boxState, +>boxState : BoxState +> : ^^^^^^^^ + + boxedObject, +>boxedObject : unknown +> : ^^^^^^^ + + } as const satisfies Box; +} + +const safeBoxedObject = boxFactorySafe("open", "some value"); +>safeBoxedObject : { readonly boxState: "open"; readonly boxedObject: unknown; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>boxFactorySafe("open", "some value") : { readonly boxState: "open"; readonly boxedObject: unknown; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>boxFactorySafe : (boxState: BS, boxedObject: unknown) => { readonly boxState: BS; readonly boxedObject: unknown; } +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"open" : "open" +> : ^^^^^^ +>"some value" : "some value" +> : ^^^^^^^^^^^^ + +// https://github.com/microsoft/TypeScript/issues/60698 + +type Table = "block" | "collection" | "space"; +>Table : Table +> : ^^^^^ + +type RecordPointer = { +>RecordPointer : RecordPointer +> : ^^^^^^^^^^^^^^^^ + + [T_ in T]: { + id: string; +>id : string +> : ^^^^^^ + + table: T_; +>table : T_ +> : ^^ + + }; +}[T]; + +function g(t: T): RecordPointer
{ +>g : (t: T) => RecordPointer
+> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>t : T +> : ^ + + const x = { table: t, id: "foo" } as const satisfies RecordPointer
; +>x : { readonly table: T; readonly id: "foo"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ table: t, id: "foo" } as const satisfies RecordPointer
: { readonly table: T; readonly id: "foo"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ table: t, id: "foo" } as const : { readonly table: Table; readonly id: "foo"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ table: t, id: "foo" } : { readonly table: Table; readonly id: "foo"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>table : Table +> : ^^^^^ +>t : Table +> : ^^^^^ +>id : "foo" +> : ^^^^^ +>"foo" : "foo" +> : ^^^^^ + + return x; // error +>x : { readonly table: T; readonly id: "foo"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +} + +export function bounceAndTakeIfA(value: AB) { +>bounceAndTakeIfA : (value: AB) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^ +>value : AB +> : ^^ + + if (value === "A") { +>value === "A" : boolean +> : ^^^^^^^ +>value : AB +> : ^^ +>"A" : "A" +> : ^^^ + + const temp = value satisfies "A" +>temp : AB +> : ^^ +>value satisfies "A" : AB +> : ^^ +>value : "A" +> : ^^^ + + const takeA: "A" = value satisfies "A"; +>takeA : "A" +> : ^^^ +>value satisfies "A" : "A" +> : ^^^ +>value : "A" +> : ^^^ + } +} + diff --git a/tests/baselines/reference/dependentReturnType2.types b/tests/baselines/reference/dependentReturnType2.types index 1adf92c29a8fd..6e3b724e6b798 100644 --- a/tests/baselines/reference/dependentReturnType2.types +++ b/tests/baselines/reference/dependentReturnType2.types @@ -927,8 +927,8 @@ class NewAgenda { > : ^^^^^^^^^^^^^^^^ >isArray : (arg: any) => arg is any[] > : ^ ^^ ^^^^^ ->name : string[] -> : ^^^^^^^^ +>name : T +> : ^ return this._createIntervalJobs(interval, name, data, options); // Ok >this._createIntervalJobs(interval, name, data, options) : Promise | undefined diff --git a/tests/baselines/reference/dependentReturnType3.types b/tests/baselines/reference/dependentReturnType3.types index ac94d85e9b9e3..6cc36b7cc0edf 100644 --- a/tests/baselines/reference/dependentReturnType3.types +++ b/tests/baselines/reference/dependentReturnType3.types @@ -924,8 +924,8 @@ class NewAgenda { > : ^^^^^^^^^^^^^^^^ >isArray : (arg: any) => arg is any[] > : ^ ^^ ^^^^^ ->name : string[] -> : ^^^^^^^^ +>name : T +> : ^ return this._createIntervalJobs(interval, name, data, options); // Ok >this._createIntervalJobs(interval, name, data, options) : Promise | undefined diff --git a/tests/baselines/reference/dependentReturnType6.types b/tests/baselines/reference/dependentReturnType6.types index f1831992e691f..357d5c9f1e37f 100644 --- a/tests/baselines/reference/dependentReturnType6.types +++ b/tests/baselines/reference/dependentReturnType6.types @@ -494,8 +494,8 @@ function f9(x: T): T extends Array ? > : ^^^^^^^^^^^^^^^^ >isArray : (arg: any) => arg is any[] > : ^ ^^ ^^^^^ ->x : number | "a"[] | "b"[] -> : ^^^^^^^^^^^^^^^^^^^^^^ +>x : T +> : ^ // If we allowed narrowing of the conditional return type, when resolving the conditional `T & ("a"[] | "b"[]) extends Array ? P : ...`, // we could infer `"a" | "b"` for `P`, and allow "a" to be returned. However, when calling `f10`, `T` could be instantiated with `"b"[]`, and the return type would be `"b"`, diff --git a/tests/baselines/reference/divideAndConquerIntersections.types b/tests/baselines/reference/divideAndConquerIntersections.types index 880c5d4a95d5a..ba191f03e1f90 100644 --- a/tests/baselines/reference/divideAndConquerIntersections.types +++ b/tests/baselines/reference/divideAndConquerIntersections.types @@ -173,8 +173,8 @@ export function matchFilter( > : ^^^^ ^^ ^^^^^ >"Matching" : "Matching" > : ^^^^^^^^^^ ->filter : "message" | "edited_message" | "channel_post" | "edited_channel_post" | "message_reaction" | "message_reaction_count" | "inline_query" | "chosen_inline_result" | "callback_query" | "shipping_query" | "pre_checkout_query" | "poll" | "poll_answer" | "my_chat_member" | "chat_member" | "chat_join_request" | "chat_boost" | "removed_chat_boost" | Q[] -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>filter : Q | Q[] +> : ^^^^^^^ return (up: U): up is Filter => !!up; >(up: U): up is Filter => !!up : (up: U) => up is Filter @@ -312,8 +312,8 @@ class EventHub { > : ^^^^^^ >"handlers for" : "handlers for" > : ^^^^^^^^^^^^^^ ->filter : "message" | "edited_message" | "channel_post" | "edited_channel_post" | "message_reaction" | "message_reaction_count" | "inline_query" | "chosen_inline_result" | "callback_query" | "shipping_query" | "pre_checkout_query" | "poll" | "poll_answer" | "my_chat_member" | "chat_member" | "chat_join_request" | "chat_boost" | "removed_chat_boost" | Q[] -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>filter : Q | Q[] +> : ^^^^^^^ return new EventHub>(); >new EventHub>() : EventHub, Q>>> diff --git a/tests/baselines/reference/inKeywordTypeguard(strict=false).types b/tests/baselines/reference/inKeywordTypeguard(strict=false).types index eaf32e71c8c0b..8362a2039d35a 100644 --- a/tests/baselines/reference/inKeywordTypeguard(strict=false).types +++ b/tests/baselines/reference/inKeywordTypeguard(strict=false).types @@ -1716,8 +1716,8 @@ function test1>(obj: T) { > : ^^^^^^^^^^^^^^^^ >isArray : (arg: any) => arg is any[] > : ^ ^^ ^^^^^ ->obj : any[] | Record -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>obj : T +> : ^ >'length' in obj : boolean > : ^^^^^^^ >'length' : "length" @@ -1751,8 +1751,8 @@ function test2>(obj: T) { > : ^^^^^^^^^^^^^^^^ >isArray : (arg: any) => arg is any[] > : ^ ^^ ^^^^^ ->obj : any[] | Record -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>obj : T +> : ^ obj; // T & any[] >obj : T & any[] diff --git a/tests/baselines/reference/inKeywordTypeguard(strict=true).types b/tests/baselines/reference/inKeywordTypeguard(strict=true).types index 118e1c698a636..08508115c148a 100644 --- a/tests/baselines/reference/inKeywordTypeguard(strict=true).types +++ b/tests/baselines/reference/inKeywordTypeguard(strict=true).types @@ -1719,8 +1719,8 @@ function test1>(obj: T) { > : ^^^^^^^^^^^^^^^^ >isArray : (arg: any) => arg is any[] > : ^ ^^ ^^^^^ ->obj : any[] | Record -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>obj : T +> : ^ >'length' in obj : boolean > : ^^^^^^^ >'length' : "length" @@ -1754,8 +1754,8 @@ function test2>(obj: T) { > : ^^^^^^^^^^^^^^^^ >isArray : (arg: any) => arg is any[] > : ^ ^^ ^^^^^ ->obj : any[] | Record -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>obj : T +> : ^ obj; // T & any[] >obj : T & any[] diff --git a/tests/baselines/reference/narrowingDestructuring.types b/tests/baselines/reference/narrowingDestructuring.types index 0041dd06ab6d5..2f7a523a0d6ba 100644 --- a/tests/baselines/reference/narrowingDestructuring.types +++ b/tests/baselines/reference/narrowingDestructuring.types @@ -188,22 +188,22 @@ function func3(t: > : ^^^^^^^^ ^^^^^ ^^^ const r2 = (({ kind, ...rest }) => rest)(t); ->r2 : { a: string; } -> : ^^^^^ ^^^ ->(({ kind, ...rest }) => rest)(t) : { a: string; } -> : ^^^^^ ^^^ ->(({ kind, ...rest }) => rest) : ({ kind, ...rest }: { kind: "a"; a: string; }) => { a: string; } -> : ^ ^^^^^^^^^^ ^^^^^ ^^^^^^^^^^^^^ ^^^ ->({ kind, ...rest }) => rest : ({ kind, ...rest }: { kind: "a"; a: string; }) => { a: string; } -> : ^ ^^^^^^^^^^ ^^^^^ ^^^^^^^^^^^^^ ^^^ ->kind : "a" -> : ^^^ ->rest : { a: string; } -> : ^^^^^ ^^^ ->rest : { a: string; } -> : ^^^^^ ^^^ ->t : { kind: "a"; a: string; } -> : ^^^^^^^^ ^^^^^ ^^^ +>r2 : Omit +> : ^^^^^^^^^^^^^^^ +>(({ kind, ...rest }) => rest)(t) : Omit +> : ^^^^^^^^^^^^^^^ +>(({ kind, ...rest }) => rest) : ({ kind, ...rest }: T) => Omit +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^ +>({ kind, ...rest }) => rest : ({ kind, ...rest }: T) => Omit +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^ +>kind : "a" | "b" +> : ^^^^^^^^^ +>rest : Omit +> : ^^^^^^^^^^^^^^^ +>rest : Omit +> : ^^^^^^^^^^^^^^^ +>t : T +> : ^ } } diff --git a/tests/baselines/reference/recursiveTypeRelations.types b/tests/baselines/reference/recursiveTypeRelations.types index 14fc3c854d501..4f01834bfc666 100644 --- a/tests/baselines/reference/recursiveTypeRelations.types +++ b/tests/baselines/reference/recursiveTypeRelations.types @@ -134,16 +134,16 @@ export function css(styles: S, ...classNam > : ^^^^^^^ obj[exportedClassName] = (arg as ClassNameMap)[key]; ->obj[exportedClassName] = (arg as ClassNameMap)[key] : boolean -> : ^^^^^^^ +>obj[exportedClassName] = (arg as ClassNameMap)[key] : ClassNameMap[keyof S] +> : ^^^^^^^^^^^^^^^^^^^^^^^^ >obj[exportedClassName] : ClassNameObject > : ^^^^^^^^^^^^^^^ >obj : ClassNameObject > : ^^^^^^^^^^^^^^^ >exportedClassName : S[keyof S] > : ^^^^^^^^^^ ->(arg as ClassNameMap)[key] : boolean -> : ^^^^^^^ +>(arg as ClassNameMap)[key] : ClassNameMap[keyof S] +> : ^^^^^^^^^^^^^^^^^^^^^^^^ >(arg as ClassNameMap) : ClassNameMap > : ^^^^^^^^^^^^^^^ >arg as ClassNameMap : ClassNameMap diff --git a/tests/baselines/reference/typeVariableConstraintIntersections.types b/tests/baselines/reference/typeVariableConstraintIntersections.types index 0bf67da2f7f16..e60cf2f5bc656 100644 --- a/tests/baselines/reference/typeVariableConstraintIntersections.types +++ b/tests/baselines/reference/typeVariableConstraintIntersections.types @@ -155,8 +155,8 @@ function foo(x: K) { > : ^^^^^^^ >isA : (x: any) => x is "a" > : ^ ^^ ^^^^^ ->x : "a" | "b" -> : ^^^^^^^^^ +>x : K +> : ^ x; // K & "a" >x : K & "a" @@ -167,8 +167,8 @@ function foo(x: K) { > : ^^^^^^^ >isB : (x: any) => x is "b" > : ^ ^^ ^^^^^ ->x : "a" | "b" -> : ^^^^^^^^^ +>x : K +> : ^ x; // K & "b" >x : K & "b" @@ -179,8 +179,8 @@ function foo(x: K) { > : ^^^^^^^ >isC : (x: any) => x is "c" > : ^ ^^ ^^^^^ ->x : "a" | "b" -> : ^^^^^^^^^ +>x : K +> : ^ x; // never >x : never @@ -193,14 +193,14 @@ function foo(x: K) { > : ^^^^^^^ >isA : (x: any) => x is "a" > : ^ ^^ ^^^^^ ->x : "a" | "b" -> : ^^^^^^^^^ +>x : K +> : ^ >isB(x) : boolean > : ^^^^^^^ >isB : (x: any) => x is "b" > : ^ ^^ ^^^^^ ->x : "b" -> : ^^^ +>x : K +> : ^ x; // K >x : K @@ -217,14 +217,14 @@ function foo(x: K) { > : ^^^^^^^ >isA : (x: any) => x is "a" > : ^ ^^ ^^^^^ ->x : "a" | "b" -> : ^^^^^^^^^ +>x : K +> : ^ >isB(x) : boolean > : ^^^^^^^ >isB : (x: any) => x is "b" > : ^ ^^ ^^^^^ ->x : "b" -> : ^^^ +>x : K +> : ^ return; } diff --git a/tests/cases/compiler/controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts b/tests/cases/compiler/controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts new file mode 100644 index 0000000000000..ea330d98b2a20 --- /dev/null +++ b/tests/cases/compiler/controlFlowGenericTypesNarrowableReferencesWithAutoTypes1.ts @@ -0,0 +1,14 @@ +// @strict: true +// @noEmit: true + +const foo_autoType = (bar: T) => { + let test1; + test1 = bar; + return test1; +}; + +const foo_autoArrayType = (bar: T) => { + let test1 = []; + test1.push(bar); + return test1; +}; diff --git a/tests/cases/compiler/controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts b/tests/cases/compiler/controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts new file mode 100644 index 0000000000000..1a3d559894a26 --- /dev/null +++ b/tests/cases/compiler/controlFlowGenericTypesNarrowableReferencesWithSatisfies1.ts @@ -0,0 +1,61 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/52394 + +const foo52394 = (bar: T) => { + const a = bar satisfies any; + return a; +}; + +type MyType52394 = { + a: string; + b: "a" | "b" | "c" | "d" | "e"; +}; +const foo2_52394 = (bar: T) => + ({ + a: bar, + b: bar, + }) satisfies MyType52394; + +type BoxState = "open" | "closed"; + +type Box = { + boxState: BoxState; + boxedObject: unknown; +}; + +function boxFactorySafe( + boxState: BS, + boxedObject: unknown, +) { + return { + boxState, + boxedObject, + } as const satisfies Box; +} + +const safeBoxedObject = boxFactorySafe("open", "some value"); + +// https://github.com/microsoft/TypeScript/issues/60698 + +type Table = "block" | "collection" | "space"; + +type RecordPointer = { + [T_ in T]: { + id: string; + table: T_; + }; +}[T]; + +function g(t: T): RecordPointer
{ + const x = { table: t, id: "foo" } as const satisfies RecordPointer
; + return x; // error +} + +export function bounceAndTakeIfA(value: AB) { + if (value === "A") { + const temp = value satisfies "A" + const takeA: "A" = value satisfies "A"; + } +} diff --git a/tests/cases/fourslash/incompleteFunctionCallCodefixTypeKeyof.ts b/tests/cases/fourslash/incompleteFunctionCallCodefixTypeKeyof.ts index ce95eb8cab030..ed6241f29a212 100644 --- a/tests/cases/fourslash/incompleteFunctionCallCodefixTypeKeyof.ts +++ b/tests/cases/fourslash/incompleteFunctionCallCodefixTypeKeyof.ts @@ -15,7 +15,7 @@ verify.codeFix({ added(keyofTypeof); } -function added(keyofTypeof: string | number | symbol) { +function added(keyofTypeof: keyof T) { throw new Error("Function not implemented."); } `, diff --git a/tests/cases/fourslash/incompleteFunctionCallCodefixTypeParameterVariable.ts b/tests/cases/fourslash/incompleteFunctionCallCodefixTypeParameterVariable.ts index 93b819724e29f..39869a362df69 100644 --- a/tests/cases/fourslash/incompleteFunctionCallCodefixTypeParameterVariable.ts +++ b/tests/cases/fourslash/incompleteFunctionCallCodefixTypeParameterVariable.ts @@ -19,7 +19,7 @@ verify.codeFix({ added2(et) } -function added1(et: string) { +function added1(et: T) { throw new Error("Function not implemented.") } `, @@ -27,8 +27,8 @@ function added1(et: string) { goTo.marker("2"); verify.codeFix({ - description: "Add missing function declaration 'added1'", - index: 0, + description: "Add missing function declaration 'added2'", + index: 1, newFileContent: `function e() { let et: T = 'phone' added1(et) @@ -36,7 +36,7 @@ verify.codeFix({ added2(et) } -function added1(et: string) { +function added2(et: T) { throw new Error("Function not implemented.") } `,