diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4f5844a8f25fe..dbda29d2e72f5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1990,6 +1990,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var markerSubTypeForCheck = createTypeParameter(); markerSubTypeForCheck.constraint = markerSuperTypeForCheck; + var declaredSyntheticInferType = createTypeParameter(); + var noTypePredicate = createTypePredicate(TypePredicateKind.Identifier, "<>", 0, anyType); var anySignature = createSignature(/*declaration*/ undefined, /*typeParameters*/ undefined, /*thisParameter*/ undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None); @@ -14863,7 +14865,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return undefined; } - function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: readonly TypeParameter[]): Signature { + function getSignatureInstantiation(signature: Signature, typeArguments: readonly Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: readonly TypeParameter[]): Signature { const instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript)); if (inferredTypeParameters) { const returnSignature = getSingleCallOrConstructSignature(getReturnTypeOfSignature(instantiatedSignature)); @@ -18485,6 +18487,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return node.flags & NodeFlags.JavaScriptFile && !noImplicitAny ? anyType : nonPrimitiveType; case SyntaxKind.IntrinsicKeyword: return intrinsicMarkerType; + case SyntaxKind.PlaceholderType: + return declaredSyntheticInferType; case SyntaxKind.ThisType: case SyntaxKind.ThisKeyword as TypeNodeSyntaxKind: // TODO(rbuckton): `ThisKeyword` is no longer a `TypeNode`, but we defensively allow it here because of incorrect casts in the Language Service and because of `isPartOfTypeNode`. @@ -32560,10 +32564,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return createTupleType(types, flags, inConstContext, length(names) === length(types) ? names : undefined); } - function checkTypeArguments(signature: Signature, typeArgumentNodes: readonly TypeNode[], reportErrors: boolean, headMessage?: DiagnosticMessage): Type[] | undefined { + function checkTypeArguments(signature: Signature, typeArgumentNodes: readonly TypeNode[], reportErrors: boolean, headMessage?: DiagnosticMessage, typeArguments?: readonly Type[]): readonly Type[] | undefined { const isJavascript = isInJSFile(signature.declaration); const typeParameters = signature.typeParameters!; - const typeArgumentTypes = fillMissingTypeArguments(map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript); + const typeArgumentTypes = typeArguments || fillMissingTypeArguments(map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript); + if (some(typeArgumentTypes, isSyntheticInferType)) { + // Do validation once partial inference is complete + return typeArgumentTypes; + } let mapper: TypeMapper | undefined; for (let i = 0; i < typeArgumentNodes.length; i++) { Debug.assert(typeParameters[i] !== undefined, "Should not call checkTypeArguments with too many type arguments"); @@ -32588,6 +32596,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return typeArgumentTypes; } + function isSyntheticInferType(type: Type) { + return type === declaredSyntheticInferType; + } + function getJsxReferenceKind(node: JsxOpeningLikeElement): JsxReferenceKind { if (isJsxIntrinsicTagName(node.tagName)) { return JsxReferenceKind.Mixed; @@ -33156,6 +33168,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let candidatesForArgumentError: Signature[] | undefined; let candidateForArgumentArityError: Signature | undefined; let candidateForTypeArgumentError: Signature | undefined; + let candidateForTypeArgumentErrorTypeArguments: readonly Type[] | undefined; let result: Signature | undefined; // If we are in signature help, a trailing comma indicates that we intend to provide another argument, @@ -33216,6 +33229,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { addRelatedInfo(d, createDiagnosticForNode(last.declaration, Diagnostics.The_last_overload_is_declared_here)); } addImplementationSuccessElaboration(last, d); + if (typeArguments && some(typeArguments, n => n.kind === SyntaxKind.PlaceholderType)) { + const underscoreType = resolveName(node, "_" as __String, SymbolFlags.Type, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); + if (underscoreType && underscoreType !== unknownSymbol) { + addRelatedInfo(d, createDiagnosticForNode(find(typeArguments, n => n.kind === SyntaxKind.PlaceholderType)!, Diagnostics.in_an_expression_type_argument_list_is_a_placeholder_type_If_you_meant_to_refer_to_the_type_named_write_0_instead)); + } + } diagnostics.add(d); } } @@ -33273,7 +33292,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args, headMessage)); } else if (candidateForTypeArgumentError) { - checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression | JsxOpeningLikeElement).typeArguments!, /*reportErrors*/ true, headMessage); + checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression | JsxOpeningLikeElement).typeArguments!, /*reportErrors*/ true, headMessage, candidateForTypeArgumentErrorTypeArguments); } else { const signaturesWithCorrectTypeArgumentArity = filter(signatures, s => hasCorrectTypeArgumentArity(s, typeArguments)); @@ -33292,6 +33311,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const oldCandidatesForArgumentError = candidatesForArgumentError; const oldCandidateForArgumentArityError = candidateForArgumentArityError; const oldCandidateForTypeArgumentError = candidateForTypeArgumentError; + const oldCandidateForTypeArgumentErrorTypeArguments = candidateForTypeArgumentErrorTypeArguments; const failedSignatureDeclarations = failed.declaration?.symbol?.declarations || emptyArray; const isOverload = failedSignatureDeclarations.length > 1; @@ -33307,12 +33327,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { candidatesForArgumentError = oldCandidatesForArgumentError; candidateForArgumentArityError = oldCandidateForArgumentArityError; candidateForTypeArgumentError = oldCandidateForTypeArgumentError; + candidateForTypeArgumentErrorTypeArguments = oldCandidateForTypeArgumentErrorTypeArguments; } function chooseOverload(candidates: Signature[], relation: Map, isSingleNonGenericCandidate: boolean, signatureHelpTrailingComma = false) { candidatesForArgumentError = undefined; candidateForArgumentArityError = undefined; candidateForTypeArgumentError = undefined; + candidateForTypeArgumentErrorTypeArguments = undefined; if (isSingleNonGenericCandidate) { const candidate = candidates[0]; @@ -33335,12 +33357,43 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let checkCandidate: Signature; let inferenceContext: InferenceContext | undefined; + const isJavascript = isInJSFile(candidate.declaration); + if (candidate.typeParameters) { - let typeArgumentTypes: Type[] | undefined; + let typeArgumentTypes: readonly Type[] | undefined; if (some(typeArguments)) { - typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false); + let typeArgumentResult = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false); + if (typeArgumentResult) { + if (some(typeArgumentResult, isSyntheticInferType)) { + // There are implied inferences we must make, despite having type arguments + const originalParams = candidate.typeParameters; + const withOriginalArgs = map(typeArgumentResult, (r, i) => isSyntheticInferType(r) ? originalParams[i] : r); + const uninferedInstantiation = getSignatureInstantiation(candidate, withOriginalArgs, isJavascript); + inferenceContext = createInferenceContext(originalParams, uninferedInstantiation, isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None); + for (let i = 0; i < inferenceContext.inferences.length; i++) { + const correspondingArgument = typeArgumentResult[i]; + if (!isSyntheticInferType(correspondingArgument)) { + const inference = inferenceContext.inferences[i]; + inference.inferredType = correspondingArgument; + inference.isFixed = true; + inference.priority = 0; + } + } + typeArgumentResult = inferTypeArguments(node, uninferedInstantiation, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext); + argCheckMode |= inferenceContext.flags & InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal; + } + } + if (typeArgumentResult) { + typeArgumentTypes = typeArgumentResult; + if (!checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false, /*headMessage*/ undefined, typeArgumentTypes)) { + candidateForTypeArgumentError = candidate; + candidateForTypeArgumentErrorTypeArguments = typeArgumentTypes; + continue; + } + } if (!typeArgumentTypes) { candidateForTypeArgumentError = candidate; + candidateForTypeArgumentErrorTypeArguments = typeArgumentTypes; continue; } } @@ -33372,7 +33425,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { argCheckMode = checkMode & CheckMode.IsForStringLiteralArgumentCompletions; if (inferenceContext) { const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext); - checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext.inferredTypeParameters); + checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isJavascript, inferenceContext.inferredTypeParameters); // If the original signature has a generic rest type, instantiation may produce a // signature with different arity and we need to perform another arity check. if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index a9dd5ddf857f2..dc9e26c412a89 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1667,6 +1667,10 @@ "category": "Message", "code": 2212 }, + "`_` in an expression type argument list is a placeholder type. If you meant to refer to the type named `_`, write `[_][0]` instead.": { + "category": "Message", + "code": 2213 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6f34ec688fc63..305578511854c 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1916,6 +1916,8 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri return emitIntersectionType(node as IntersectionTypeNode); case SyntaxKind.ConditionalType: return emitConditionalType(node as ConditionalTypeNode); + case SyntaxKind.PlaceholderType: + return emitPlaceholderType(); case SyntaxKind.InferType: return emitInferType(node as InferTypeNode); case SyntaxKind.ParenthesizedType: @@ -2836,6 +2838,10 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri emit(node.falseType); } + function emitPlaceholderType() { + write("_"); + } + function emitInferType(node: InferTypeNode) { writeKeyword("infer"); writeSpace(); diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 638ff154747fa..3a7326fcc1c26 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -354,6 +354,7 @@ import { parseNodeFactory, PartiallyEmittedExpression, Path, + PlaceholderTypeNode, PlusToken, PostfixUnaryExpression, PostfixUnaryOperator, @@ -616,6 +617,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode updateConditionalTypeNode, createInferTypeNode, updateInferTypeNode, + createPlaceholderTypeNode, createImportTypeNode, updateImportTypeNode, createParenthesizedType, @@ -2457,6 +2459,13 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode : node; } + // @api + function createPlaceholderTypeNode() { + const node = createBaseNode(SyntaxKind.PlaceholderType); + node.transformFlags = TransformFlags.ContainsTypeScript; + return node; + } + // @api function createInferTypeNode(typeParameter: TypeParameterDeclaration) { const node = createBaseNode(SyntaxKind.InferType); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index f49b48bb44295..2037651dde543 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4844,6 +4844,25 @@ namespace Parser { return finishNode(factory.createTypePredicateNode(assertsModifier, parameterName, type), pos); } + function isEndOfTypeArgument(): boolean { + nextToken(); + switch (token()) { + case SyntaxKind.CommaToken: + case SyntaxKind.GreaterThanToken: + return true; + } + return false; + } + + function parsePlaceholderOrType(): TypeNode { + if (token() === SyntaxKind.Identifier && scanner.getTokenText() === "_" && lookAhead(isEndOfTypeArgument)) { + const pos = getNodePos(); + nextToken(); + return finishNode(factory.createPlaceholderTypeNode(), pos); + } + return parseType(); + } + function parseType(): TypeNode { if (contextFlags & NodeFlags.TypeExcludesFlags) { return doOutsideOfContext(NodeFlags.TypeExcludesFlags, parseType); @@ -6086,7 +6105,7 @@ namespace Parser { return finishNode(factory.createJsxOpeningFragment(), pos); } const tagName = parseJsxElementName(); - const typeArguments = (contextFlags & NodeFlags.JavaScriptFile) === 0 ? tryParseTypeArguments() : undefined; + const typeArguments = (contextFlags & NodeFlags.JavaScriptFile) === 0 ? tryParseTypeArguments(/*inferencePosition*/ true) : undefined; const attributes = parseJsxAttributes(); let node: JsxOpeningLikeElement; @@ -6452,7 +6471,7 @@ namespace Parser { } nextToken(); - const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType); + const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parsePlaceholderOrType); if (reScanGreaterToken() !== SyntaxKind.GreaterThanToken) { // If it doesn't have the closing `>` then it's definitely not an type argument list. return undefined; @@ -8004,9 +8023,9 @@ namespace Parser { return finishNode(factory.createExpressionWithTypeArguments(expression, typeArguments), pos); } - function tryParseTypeArguments(): NodeArray | undefined { + function tryParseTypeArguments(inferencePosition?: boolean): NodeArray | undefined { return token() === SyntaxKind.LessThanToken ? - parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken) : undefined; + parseBracketedList(ParsingContext.TypeArguments, inferencePosition ? parsePlaceholderOrType : parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken) : undefined; } function isHeritageClause(): boolean { diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 6fec0b61bd294..270149576cbbe 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -637,6 +637,8 @@ export function transformTypeScript(context: TransformationContext) { case SyntaxKind.IndexedAccessType: case SyntaxKind.MappedType: case SyntaxKind.LiteralType: + case SyntaxKind.PlaceholderType: + case SyntaxKind.InferType: // TypeScript type nodes are elided. // falls through diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d5c402ea30784..62eb14711b60f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -268,6 +268,7 @@ export const enum SyntaxKind { NamedTupleMember, TemplateLiteralType, TemplateLiteralTypeSpan, + PlaceholderType, ImportType, // Binding patterns ObjectBindingPattern, @@ -741,6 +742,7 @@ export type TypeNodeSyntaxKind = | SyntaxKind.JSDocNamepathType | SyntaxKind.JSDocSignature | SyntaxKind.JSDocTypeLiteral + | SyntaxKind.PlaceholderType ; export type TokenSyntaxKind = @@ -2162,6 +2164,10 @@ export interface TypeNode extends Node { readonly kind: TypeNodeSyntaxKind; } +export interface PlaceholderTypeNode extends TypeNode { + readonly kind: SyntaxKind.PlaceholderType; +} + export interface KeywordTypeNode extends KeywordToken, TypeNode { readonly kind: TKind; } @@ -8432,6 +8438,7 @@ export interface NodeFactory { updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode; updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode; + createPlaceholderTypeNode(): PlaceholderTypeNode; createImportTypeNode(argument: TypeNode, assertions?: ImportTypeAssertionContainer, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf?: boolean): ImportTypeNode; updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, assertions: ImportTypeAssertionContainer | undefined, qualifier: EntityName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf?: boolean): ImportTypeNode; createParenthesizedType(type: TypeNode): ParenthesizedTypeNode; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 56c4b49ff6df2..634d105416c30 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4301,167 +4301,168 @@ declare namespace ts { NamedTupleMember = 201, TemplateLiteralType = 202, TemplateLiteralTypeSpan = 203, - ImportType = 204, - ObjectBindingPattern = 205, - ArrayBindingPattern = 206, - BindingElement = 207, - ArrayLiteralExpression = 208, - ObjectLiteralExpression = 209, - PropertyAccessExpression = 210, - ElementAccessExpression = 211, - CallExpression = 212, - NewExpression = 213, - TaggedTemplateExpression = 214, - TypeAssertionExpression = 215, - ParenthesizedExpression = 216, - FunctionExpression = 217, - ArrowFunction = 218, - DeleteExpression = 219, - TypeOfExpression = 220, - VoidExpression = 221, - AwaitExpression = 222, - PrefixUnaryExpression = 223, - PostfixUnaryExpression = 224, - BinaryExpression = 225, - ConditionalExpression = 226, - TemplateExpression = 227, - YieldExpression = 228, - SpreadElement = 229, - ClassExpression = 230, - OmittedExpression = 231, - ExpressionWithTypeArguments = 232, - AsExpression = 233, - NonNullExpression = 234, - MetaProperty = 235, - SyntheticExpression = 236, - SatisfiesExpression = 237, - TemplateSpan = 238, - SemicolonClassElement = 239, - Block = 240, - EmptyStatement = 241, - VariableStatement = 242, - ExpressionStatement = 243, - IfStatement = 244, - DoStatement = 245, - WhileStatement = 246, - ForStatement = 247, - ForInStatement = 248, - ForOfStatement = 249, - ContinueStatement = 250, - BreakStatement = 251, - ReturnStatement = 252, - WithStatement = 253, - SwitchStatement = 254, - LabeledStatement = 255, - ThrowStatement = 256, - TryStatement = 257, - DebuggerStatement = 258, - VariableDeclaration = 259, - VariableDeclarationList = 260, - FunctionDeclaration = 261, - ClassDeclaration = 262, - InterfaceDeclaration = 263, - TypeAliasDeclaration = 264, - EnumDeclaration = 265, - ModuleDeclaration = 266, - ModuleBlock = 267, - CaseBlock = 268, - NamespaceExportDeclaration = 269, - ImportEqualsDeclaration = 270, - ImportDeclaration = 271, - ImportClause = 272, - NamespaceImport = 273, - NamedImports = 274, - ImportSpecifier = 275, - ExportAssignment = 276, - ExportDeclaration = 277, - NamedExports = 278, - NamespaceExport = 279, - ExportSpecifier = 280, - MissingDeclaration = 281, - ExternalModuleReference = 282, - JsxElement = 283, - JsxSelfClosingElement = 284, - JsxOpeningElement = 285, - JsxClosingElement = 286, - JsxFragment = 287, - JsxOpeningFragment = 288, - JsxClosingFragment = 289, - JsxAttribute = 290, - JsxAttributes = 291, - JsxSpreadAttribute = 292, - JsxExpression = 293, - JsxNamespacedName = 294, - CaseClause = 295, - DefaultClause = 296, - HeritageClause = 297, - CatchClause = 298, - AssertClause = 299, - AssertEntry = 300, - ImportTypeAssertionContainer = 301, - PropertyAssignment = 302, - ShorthandPropertyAssignment = 303, - SpreadAssignment = 304, - EnumMember = 305, - /** @deprecated */ UnparsedPrologue = 306, - /** @deprecated */ UnparsedPrepend = 307, - /** @deprecated */ UnparsedText = 308, - /** @deprecated */ UnparsedInternalText = 309, - /** @deprecated */ UnparsedSyntheticReference = 310, - SourceFile = 311, - Bundle = 312, - /** @deprecated */ UnparsedSource = 313, - /** @deprecated */ InputFiles = 314, - JSDocTypeExpression = 315, - JSDocNameReference = 316, - JSDocMemberName = 317, - JSDocAllType = 318, - JSDocUnknownType = 319, - JSDocNullableType = 320, - JSDocNonNullableType = 321, - JSDocOptionalType = 322, - JSDocFunctionType = 323, - JSDocVariadicType = 324, - JSDocNamepathType = 325, - JSDoc = 326, + PlaceholderType = 204, + ImportType = 205, + ObjectBindingPattern = 206, + ArrayBindingPattern = 207, + BindingElement = 208, + ArrayLiteralExpression = 209, + ObjectLiteralExpression = 210, + PropertyAccessExpression = 211, + ElementAccessExpression = 212, + CallExpression = 213, + NewExpression = 214, + TaggedTemplateExpression = 215, + TypeAssertionExpression = 216, + ParenthesizedExpression = 217, + FunctionExpression = 218, + ArrowFunction = 219, + DeleteExpression = 220, + TypeOfExpression = 221, + VoidExpression = 222, + AwaitExpression = 223, + PrefixUnaryExpression = 224, + PostfixUnaryExpression = 225, + BinaryExpression = 226, + ConditionalExpression = 227, + TemplateExpression = 228, + YieldExpression = 229, + SpreadElement = 230, + ClassExpression = 231, + OmittedExpression = 232, + ExpressionWithTypeArguments = 233, + AsExpression = 234, + NonNullExpression = 235, + MetaProperty = 236, + SyntheticExpression = 237, + SatisfiesExpression = 238, + TemplateSpan = 239, + SemicolonClassElement = 240, + Block = 241, + EmptyStatement = 242, + VariableStatement = 243, + ExpressionStatement = 244, + IfStatement = 245, + DoStatement = 246, + WhileStatement = 247, + ForStatement = 248, + ForInStatement = 249, + ForOfStatement = 250, + ContinueStatement = 251, + BreakStatement = 252, + ReturnStatement = 253, + WithStatement = 254, + SwitchStatement = 255, + LabeledStatement = 256, + ThrowStatement = 257, + TryStatement = 258, + DebuggerStatement = 259, + VariableDeclaration = 260, + VariableDeclarationList = 261, + FunctionDeclaration = 262, + ClassDeclaration = 263, + InterfaceDeclaration = 264, + TypeAliasDeclaration = 265, + EnumDeclaration = 266, + ModuleDeclaration = 267, + ModuleBlock = 268, + CaseBlock = 269, + NamespaceExportDeclaration = 270, + ImportEqualsDeclaration = 271, + ImportDeclaration = 272, + ImportClause = 273, + NamespaceImport = 274, + NamedImports = 275, + ImportSpecifier = 276, + ExportAssignment = 277, + ExportDeclaration = 278, + NamedExports = 279, + NamespaceExport = 280, + ExportSpecifier = 281, + MissingDeclaration = 282, + ExternalModuleReference = 283, + JsxElement = 284, + JsxSelfClosingElement = 285, + JsxOpeningElement = 286, + JsxClosingElement = 287, + JsxFragment = 288, + JsxOpeningFragment = 289, + JsxClosingFragment = 290, + JsxAttribute = 291, + JsxAttributes = 292, + JsxSpreadAttribute = 293, + JsxExpression = 294, + JsxNamespacedName = 295, + CaseClause = 296, + DefaultClause = 297, + HeritageClause = 298, + CatchClause = 299, + AssertClause = 300, + AssertEntry = 301, + ImportTypeAssertionContainer = 302, + PropertyAssignment = 303, + ShorthandPropertyAssignment = 304, + SpreadAssignment = 305, + EnumMember = 306, + /** @deprecated */ UnparsedPrologue = 307, + /** @deprecated */ UnparsedPrepend = 308, + /** @deprecated */ UnparsedText = 309, + /** @deprecated */ UnparsedInternalText = 310, + /** @deprecated */ UnparsedSyntheticReference = 311, + SourceFile = 312, + Bundle = 313, + /** @deprecated */ UnparsedSource = 314, + /** @deprecated */ InputFiles = 315, + JSDocTypeExpression = 316, + JSDocNameReference = 317, + JSDocMemberName = 318, + JSDocAllType = 319, + JSDocUnknownType = 320, + JSDocNullableType = 321, + JSDocNonNullableType = 322, + JSDocOptionalType = 323, + JSDocFunctionType = 324, + JSDocVariadicType = 325, + JSDocNamepathType = 326, + JSDoc = 327, /** @deprecated Use SyntaxKind.JSDoc */ - JSDocComment = 326, - JSDocText = 327, - JSDocTypeLiteral = 328, - JSDocSignature = 329, - JSDocLink = 330, - JSDocLinkCode = 331, - JSDocLinkPlain = 332, - JSDocTag = 333, - JSDocAugmentsTag = 334, - JSDocImplementsTag = 335, - JSDocAuthorTag = 336, - JSDocDeprecatedTag = 337, - JSDocClassTag = 338, - JSDocPublicTag = 339, - JSDocPrivateTag = 340, - JSDocProtectedTag = 341, - JSDocReadonlyTag = 342, - JSDocOverrideTag = 343, - JSDocCallbackTag = 344, - JSDocOverloadTag = 345, - JSDocEnumTag = 346, - JSDocParameterTag = 347, - JSDocReturnTag = 348, - JSDocThisTag = 349, - JSDocTypeTag = 350, - JSDocTemplateTag = 351, - JSDocTypedefTag = 352, - JSDocSeeTag = 353, - JSDocPropertyTag = 354, - JSDocThrowsTag = 355, - JSDocSatisfiesTag = 356, - SyntaxList = 357, - NotEmittedStatement = 358, - PartiallyEmittedExpression = 359, - CommaListExpression = 360, - SyntheticReferenceExpression = 361, - Count = 362, + JSDocComment = 327, + JSDocText = 328, + JSDocTypeLiteral = 329, + JSDocSignature = 330, + JSDocLink = 331, + JSDocLinkCode = 332, + JSDocLinkPlain = 333, + JSDocTag = 334, + JSDocAugmentsTag = 335, + JSDocImplementsTag = 336, + JSDocAuthorTag = 337, + JSDocDeprecatedTag = 338, + JSDocClassTag = 339, + JSDocPublicTag = 340, + JSDocPrivateTag = 341, + JSDocProtectedTag = 342, + JSDocReadonlyTag = 343, + JSDocOverrideTag = 344, + JSDocCallbackTag = 345, + JSDocOverloadTag = 346, + JSDocEnumTag = 347, + JSDocParameterTag = 348, + JSDocReturnTag = 349, + JSDocThisTag = 350, + JSDocTypeTag = 351, + JSDocTemplateTag = 352, + JSDocTypedefTag = 353, + JSDocSeeTag = 354, + JSDocPropertyTag = 355, + JSDocThrowsTag = 356, + JSDocSatisfiesTag = 357, + SyntaxList = 358, + NotEmittedStatement = 359, + PartiallyEmittedExpression = 360, + CommaListExpression = 361, + SyntheticReferenceExpression = 362, + Count = 363, FirstAssignment = 64, LastAssignment = 79, FirstCompoundAssignment = 65, @@ -4473,7 +4474,7 @@ declare namespace ts { FirstFutureReservedWord = 119, LastFutureReservedWord = 127, FirstTypeNode = 181, - LastTypeNode = 204, + LastTypeNode = 205, FirstPunctuation = 19, LastPunctuation = 79, FirstToken = 0, @@ -4486,13 +4487,13 @@ declare namespace ts { LastTemplateToken = 18, FirstBinaryOperator = 30, LastBinaryOperator = 79, - FirstStatement = 242, - LastStatement = 258, + FirstStatement = 243, + LastStatement = 259, FirstNode = 165, - FirstJSDocNode = 315, - LastJSDocNode = 356, - FirstJSDocTagNode = 333, - LastJSDocTagNode = 356 + FirstJSDocNode = 316, + LastJSDocNode = 357, + FirstJSDocTagNode = 334, + LastJSDocTagNode = 357 } type TriviaSyntaxKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia | SyntaxKind.NewLineTrivia | SyntaxKind.WhitespaceTrivia | SyntaxKind.ShebangTrivia | SyntaxKind.ConflictMarkerTrivia; type LiteralSyntaxKind = SyntaxKind.NumericLiteral | SyntaxKind.BigIntLiteral | SyntaxKind.StringLiteral | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.RegularExpressionLiteral | SyntaxKind.NoSubstitutionTemplateLiteral; @@ -4915,6 +4916,9 @@ declare namespace ts { interface TypeNode extends Node { _typeNodeBrand: any; } + interface PlaceholderTypeNode extends TypeNode { + readonly kind: SyntaxKind.PlaceholderType; + } interface KeywordTypeNode extends KeywordToken, TypeNode { readonly kind: TKind; } @@ -7705,6 +7709,7 @@ declare namespace ts { updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode; updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode; + createPlaceholderTypeNode(): PlaceholderTypeNode; createImportTypeNode(argument: TypeNode, assertions?: ImportTypeAssertionContainer, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf?: boolean): ImportTypeNode; updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, assertions: ImportTypeAssertionContainer | undefined, qualifier: EntityName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf?: boolean): ImportTypeNode; createParenthesizedType(type: TypeNode): ParenthesizedTypeNode; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 2b642a091ce2e..2e632cc9b10ca 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -248,167 +248,168 @@ declare namespace ts { NamedTupleMember = 201, TemplateLiteralType = 202, TemplateLiteralTypeSpan = 203, - ImportType = 204, - ObjectBindingPattern = 205, - ArrayBindingPattern = 206, - BindingElement = 207, - ArrayLiteralExpression = 208, - ObjectLiteralExpression = 209, - PropertyAccessExpression = 210, - ElementAccessExpression = 211, - CallExpression = 212, - NewExpression = 213, - TaggedTemplateExpression = 214, - TypeAssertionExpression = 215, - ParenthesizedExpression = 216, - FunctionExpression = 217, - ArrowFunction = 218, - DeleteExpression = 219, - TypeOfExpression = 220, - VoidExpression = 221, - AwaitExpression = 222, - PrefixUnaryExpression = 223, - PostfixUnaryExpression = 224, - BinaryExpression = 225, - ConditionalExpression = 226, - TemplateExpression = 227, - YieldExpression = 228, - SpreadElement = 229, - ClassExpression = 230, - OmittedExpression = 231, - ExpressionWithTypeArguments = 232, - AsExpression = 233, - NonNullExpression = 234, - MetaProperty = 235, - SyntheticExpression = 236, - SatisfiesExpression = 237, - TemplateSpan = 238, - SemicolonClassElement = 239, - Block = 240, - EmptyStatement = 241, - VariableStatement = 242, - ExpressionStatement = 243, - IfStatement = 244, - DoStatement = 245, - WhileStatement = 246, - ForStatement = 247, - ForInStatement = 248, - ForOfStatement = 249, - ContinueStatement = 250, - BreakStatement = 251, - ReturnStatement = 252, - WithStatement = 253, - SwitchStatement = 254, - LabeledStatement = 255, - ThrowStatement = 256, - TryStatement = 257, - DebuggerStatement = 258, - VariableDeclaration = 259, - VariableDeclarationList = 260, - FunctionDeclaration = 261, - ClassDeclaration = 262, - InterfaceDeclaration = 263, - TypeAliasDeclaration = 264, - EnumDeclaration = 265, - ModuleDeclaration = 266, - ModuleBlock = 267, - CaseBlock = 268, - NamespaceExportDeclaration = 269, - ImportEqualsDeclaration = 270, - ImportDeclaration = 271, - ImportClause = 272, - NamespaceImport = 273, - NamedImports = 274, - ImportSpecifier = 275, - ExportAssignment = 276, - ExportDeclaration = 277, - NamedExports = 278, - NamespaceExport = 279, - ExportSpecifier = 280, - MissingDeclaration = 281, - ExternalModuleReference = 282, - JsxElement = 283, - JsxSelfClosingElement = 284, - JsxOpeningElement = 285, - JsxClosingElement = 286, - JsxFragment = 287, - JsxOpeningFragment = 288, - JsxClosingFragment = 289, - JsxAttribute = 290, - JsxAttributes = 291, - JsxSpreadAttribute = 292, - JsxExpression = 293, - JsxNamespacedName = 294, - CaseClause = 295, - DefaultClause = 296, - HeritageClause = 297, - CatchClause = 298, - AssertClause = 299, - AssertEntry = 300, - ImportTypeAssertionContainer = 301, - PropertyAssignment = 302, - ShorthandPropertyAssignment = 303, - SpreadAssignment = 304, - EnumMember = 305, - /** @deprecated */ UnparsedPrologue = 306, - /** @deprecated */ UnparsedPrepend = 307, - /** @deprecated */ UnparsedText = 308, - /** @deprecated */ UnparsedInternalText = 309, - /** @deprecated */ UnparsedSyntheticReference = 310, - SourceFile = 311, - Bundle = 312, - /** @deprecated */ UnparsedSource = 313, - /** @deprecated */ InputFiles = 314, - JSDocTypeExpression = 315, - JSDocNameReference = 316, - JSDocMemberName = 317, - JSDocAllType = 318, - JSDocUnknownType = 319, - JSDocNullableType = 320, - JSDocNonNullableType = 321, - JSDocOptionalType = 322, - JSDocFunctionType = 323, - JSDocVariadicType = 324, - JSDocNamepathType = 325, - JSDoc = 326, + PlaceholderType = 204, + ImportType = 205, + ObjectBindingPattern = 206, + ArrayBindingPattern = 207, + BindingElement = 208, + ArrayLiteralExpression = 209, + ObjectLiteralExpression = 210, + PropertyAccessExpression = 211, + ElementAccessExpression = 212, + CallExpression = 213, + NewExpression = 214, + TaggedTemplateExpression = 215, + TypeAssertionExpression = 216, + ParenthesizedExpression = 217, + FunctionExpression = 218, + ArrowFunction = 219, + DeleteExpression = 220, + TypeOfExpression = 221, + VoidExpression = 222, + AwaitExpression = 223, + PrefixUnaryExpression = 224, + PostfixUnaryExpression = 225, + BinaryExpression = 226, + ConditionalExpression = 227, + TemplateExpression = 228, + YieldExpression = 229, + SpreadElement = 230, + ClassExpression = 231, + OmittedExpression = 232, + ExpressionWithTypeArguments = 233, + AsExpression = 234, + NonNullExpression = 235, + MetaProperty = 236, + SyntheticExpression = 237, + SatisfiesExpression = 238, + TemplateSpan = 239, + SemicolonClassElement = 240, + Block = 241, + EmptyStatement = 242, + VariableStatement = 243, + ExpressionStatement = 244, + IfStatement = 245, + DoStatement = 246, + WhileStatement = 247, + ForStatement = 248, + ForInStatement = 249, + ForOfStatement = 250, + ContinueStatement = 251, + BreakStatement = 252, + ReturnStatement = 253, + WithStatement = 254, + SwitchStatement = 255, + LabeledStatement = 256, + ThrowStatement = 257, + TryStatement = 258, + DebuggerStatement = 259, + VariableDeclaration = 260, + VariableDeclarationList = 261, + FunctionDeclaration = 262, + ClassDeclaration = 263, + InterfaceDeclaration = 264, + TypeAliasDeclaration = 265, + EnumDeclaration = 266, + ModuleDeclaration = 267, + ModuleBlock = 268, + CaseBlock = 269, + NamespaceExportDeclaration = 270, + ImportEqualsDeclaration = 271, + ImportDeclaration = 272, + ImportClause = 273, + NamespaceImport = 274, + NamedImports = 275, + ImportSpecifier = 276, + ExportAssignment = 277, + ExportDeclaration = 278, + NamedExports = 279, + NamespaceExport = 280, + ExportSpecifier = 281, + MissingDeclaration = 282, + ExternalModuleReference = 283, + JsxElement = 284, + JsxSelfClosingElement = 285, + JsxOpeningElement = 286, + JsxClosingElement = 287, + JsxFragment = 288, + JsxOpeningFragment = 289, + JsxClosingFragment = 290, + JsxAttribute = 291, + JsxAttributes = 292, + JsxSpreadAttribute = 293, + JsxExpression = 294, + JsxNamespacedName = 295, + CaseClause = 296, + DefaultClause = 297, + HeritageClause = 298, + CatchClause = 299, + AssertClause = 300, + AssertEntry = 301, + ImportTypeAssertionContainer = 302, + PropertyAssignment = 303, + ShorthandPropertyAssignment = 304, + SpreadAssignment = 305, + EnumMember = 306, + /** @deprecated */ UnparsedPrologue = 307, + /** @deprecated */ UnparsedPrepend = 308, + /** @deprecated */ UnparsedText = 309, + /** @deprecated */ UnparsedInternalText = 310, + /** @deprecated */ UnparsedSyntheticReference = 311, + SourceFile = 312, + Bundle = 313, + /** @deprecated */ UnparsedSource = 314, + /** @deprecated */ InputFiles = 315, + JSDocTypeExpression = 316, + JSDocNameReference = 317, + JSDocMemberName = 318, + JSDocAllType = 319, + JSDocUnknownType = 320, + JSDocNullableType = 321, + JSDocNonNullableType = 322, + JSDocOptionalType = 323, + JSDocFunctionType = 324, + JSDocVariadicType = 325, + JSDocNamepathType = 326, + JSDoc = 327, /** @deprecated Use SyntaxKind.JSDoc */ - JSDocComment = 326, - JSDocText = 327, - JSDocTypeLiteral = 328, - JSDocSignature = 329, - JSDocLink = 330, - JSDocLinkCode = 331, - JSDocLinkPlain = 332, - JSDocTag = 333, - JSDocAugmentsTag = 334, - JSDocImplementsTag = 335, - JSDocAuthorTag = 336, - JSDocDeprecatedTag = 337, - JSDocClassTag = 338, - JSDocPublicTag = 339, - JSDocPrivateTag = 340, - JSDocProtectedTag = 341, - JSDocReadonlyTag = 342, - JSDocOverrideTag = 343, - JSDocCallbackTag = 344, - JSDocOverloadTag = 345, - JSDocEnumTag = 346, - JSDocParameterTag = 347, - JSDocReturnTag = 348, - JSDocThisTag = 349, - JSDocTypeTag = 350, - JSDocTemplateTag = 351, - JSDocTypedefTag = 352, - JSDocSeeTag = 353, - JSDocPropertyTag = 354, - JSDocThrowsTag = 355, - JSDocSatisfiesTag = 356, - SyntaxList = 357, - NotEmittedStatement = 358, - PartiallyEmittedExpression = 359, - CommaListExpression = 360, - SyntheticReferenceExpression = 361, - Count = 362, + JSDocComment = 327, + JSDocText = 328, + JSDocTypeLiteral = 329, + JSDocSignature = 330, + JSDocLink = 331, + JSDocLinkCode = 332, + JSDocLinkPlain = 333, + JSDocTag = 334, + JSDocAugmentsTag = 335, + JSDocImplementsTag = 336, + JSDocAuthorTag = 337, + JSDocDeprecatedTag = 338, + JSDocClassTag = 339, + JSDocPublicTag = 340, + JSDocPrivateTag = 341, + JSDocProtectedTag = 342, + JSDocReadonlyTag = 343, + JSDocOverrideTag = 344, + JSDocCallbackTag = 345, + JSDocOverloadTag = 346, + JSDocEnumTag = 347, + JSDocParameterTag = 348, + JSDocReturnTag = 349, + JSDocThisTag = 350, + JSDocTypeTag = 351, + JSDocTemplateTag = 352, + JSDocTypedefTag = 353, + JSDocSeeTag = 354, + JSDocPropertyTag = 355, + JSDocThrowsTag = 356, + JSDocSatisfiesTag = 357, + SyntaxList = 358, + NotEmittedStatement = 359, + PartiallyEmittedExpression = 360, + CommaListExpression = 361, + SyntheticReferenceExpression = 362, + Count = 363, FirstAssignment = 64, LastAssignment = 79, FirstCompoundAssignment = 65, @@ -420,7 +421,7 @@ declare namespace ts { FirstFutureReservedWord = 119, LastFutureReservedWord = 127, FirstTypeNode = 181, - LastTypeNode = 204, + LastTypeNode = 205, FirstPunctuation = 19, LastPunctuation = 79, FirstToken = 0, @@ -433,13 +434,13 @@ declare namespace ts { LastTemplateToken = 18, FirstBinaryOperator = 30, LastBinaryOperator = 79, - FirstStatement = 242, - LastStatement = 258, + FirstStatement = 243, + LastStatement = 259, FirstNode = 165, - FirstJSDocNode = 315, - LastJSDocNode = 356, - FirstJSDocTagNode = 333, - LastJSDocTagNode = 356 + FirstJSDocNode = 316, + LastJSDocNode = 357, + FirstJSDocTagNode = 334, + LastJSDocTagNode = 357 } type TriviaSyntaxKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia | SyntaxKind.NewLineTrivia | SyntaxKind.WhitespaceTrivia | SyntaxKind.ShebangTrivia | SyntaxKind.ConflictMarkerTrivia; type LiteralSyntaxKind = SyntaxKind.NumericLiteral | SyntaxKind.BigIntLiteral | SyntaxKind.StringLiteral | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.RegularExpressionLiteral | SyntaxKind.NoSubstitutionTemplateLiteral; @@ -862,6 +863,9 @@ declare namespace ts { interface TypeNode extends Node { _typeNodeBrand: any; } + interface PlaceholderTypeNode extends TypeNode { + readonly kind: SyntaxKind.PlaceholderType; + } interface KeywordTypeNode extends KeywordToken, TypeNode { readonly kind: TKind; } @@ -3652,6 +3656,7 @@ declare namespace ts { updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode; updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode; + createPlaceholderTypeNode(): PlaceholderTypeNode; createImportTypeNode(argument: TypeNode, assertions?: ImportTypeAssertionContainer, qualifier?: EntityName, typeArguments?: readonly TypeNode[], isTypeOf?: boolean): ImportTypeNode; updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, assertions: ImportTypeAssertionContainer | undefined, qualifier: EntityName | undefined, typeArguments: readonly TypeNode[] | undefined, isTypeOf?: boolean): ImportTypeNode; createParenthesizedType(type: TypeNode): ParenthesizedTypeNode; diff --git a/tests/baselines/reference/inferPartialTypeArguments.errors.txt b/tests/baselines/reference/inferPartialTypeArguments.errors.txt new file mode 100644 index 0000000000000..b9687552d11cc --- /dev/null +++ b/tests/baselines/reference/inferPartialTypeArguments.errors.txt @@ -0,0 +1,58 @@ +tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArguments.tsx(35,40): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArguments.tsx(36,35): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + + +==== tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArguments.tsx (2 errors) ==== + declare module JSX { + interface Element {} + } + declare namespace React { + export function createElement(x: any, p: any, ...children: any[]): JSX.Element; + } + class Foo { + constructor(public prop1: T, public prop2: U) {} + } + function foo(x: T, y: U): [T, U] { return [x, y]; } + function tag(x: TemplateStringsArray, ...args: (T | U)[]) { return args; } + interface ComponentProps { + x: T; + y: U; + cb(props: this): void; + } + function Component(x: ComponentProps) { + return ; + } + + const instance1 = new Foo(0, ""); + const result1 = foo(0, ""); + const tagged1 = tag`tags ${12} ${""}`; + const jsx1 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + + const instance2 = new Foo<_, string>(0, ""); + const result2 = foo<_, string>(0, ""); + const tagged2 = tag<_, string>`tags ${12} ${""}`; + const jsx2 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + + const instance3 = new Foo<_, _>(0, ""); + const _instance3 = new Foo(0, ""); + const result3 = foo<_, _>(0, ""); + const _result3 = foo(0, ""); + const tagged3 = tag<_, _>`tags ${12} ${""}`; + ~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + const _tagged3 = tag`tags ${12} ${""}`; + ~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + const jsx3 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + const _jsx3 = void (props.x.toFixed() + props.y.toUpperCase())} />; + + declare function stillDefaultsIfNoInference(arg: { a?: A, b?: B, c?: C, x?: X}): { a: A, b: B, c: C, x: X }; + const result4 = stillDefaultsIfNoInference<_, _, _, object> ({ b: "test" }); // expect result1 type is {a: string, b: string, c: object, x: {} + + class Foo2 { + constructor(public a?: A, public b?: B) {} + } + const x = new Foo2<_, string>(); + x.a.x; + x.a.y; + x.b; \ No newline at end of file diff --git a/tests/baselines/reference/inferPartialTypeArguments.js b/tests/baselines/reference/inferPartialTypeArguments.js new file mode 100644 index 0000000000000..be77f1d26e34b --- /dev/null +++ b/tests/baselines/reference/inferPartialTypeArguments.js @@ -0,0 +1,102 @@ +//// [inferPartialTypeArguments.tsx] +declare module JSX { + interface Element {} +} +declare namespace React { + export function createElement(x: any, p: any, ...children: any[]): JSX.Element; +} + class Foo { + constructor(public prop1: T, public prop2: U) {} +} + function foo(x: T, y: U): [T, U] { return [x, y]; } + function tag(x: TemplateStringsArray, ...args: (T | U)[]) { return args; } + interface ComponentProps { + x: T; + y: U; + cb(props: this): void; +} + function Component(x: ComponentProps) { + return ; +} + +const instance1 = new Foo(0, ""); +const result1 = foo(0, ""); +const tagged1 = tag`tags ${12} ${""}`; +const jsx1 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + +const instance2 = new Foo<_, string>(0, ""); +const result2 = foo<_, string>(0, ""); +const tagged2 = tag<_, string>`tags ${12} ${""}`; +const jsx2 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + +const instance3 = new Foo<_, _>(0, ""); +const _instance3 = new Foo(0, ""); +const result3 = foo<_, _>(0, ""); +const _result3 = foo(0, ""); +const tagged3 = tag<_, _>`tags ${12} ${""}`; +const _tagged3 = tag`tags ${12} ${""}`; +const jsx3 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +const _jsx3 = void (props.x.toFixed() + props.y.toUpperCase())} />; + +declare function stillDefaultsIfNoInference(arg: { a?: A, b?: B, c?: C, x?: X}): { a: A, b: B, c: C, x: X }; +const result4 = stillDefaultsIfNoInference<_, _, _, object> ({ b: "test" }); // expect result1 type is {a: string, b: string, c: object, x: {} + +class Foo2 { + constructor(public a?: A, public b?: B) {} +} +const x = new Foo2<_, string>(); +x.a.x; +x.a.y; +x.b; + +//// [inferPartialTypeArguments.js] +var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; +}; +var Foo = /** @class */ (function () { + function Foo(prop1, prop2) { + this.prop1 = prop1; + this.prop2 = prop2; + } + return Foo; +}()); +function foo(x, y) { return [x, y]; } +function tag(x) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + return args; +} +function Component(x) { + return React.createElement("h", null); +} +var instance1 = new Foo(0, ""); +var result1 = foo(0, ""); +var tagged1 = tag(__makeTemplateObject(["tags ", " ", ""], ["tags ", " ", ""]), 12, ""); +var jsx1 = React.createElement(Component, { x: 12, y: "", cb: function (props) { return void (props.x.toFixed() + props.y.toUpperCase()); } }); +var instance2 = new Foo(0, ""); +var result2 = foo(0, ""); +var tagged2 = tag(__makeTemplateObject(["tags ", " ", ""], ["tags ", " ", ""]), 12, ""); +var jsx2 = React.createElement(Component, { x: 12, y: "", cb: function (props) { return void (props.x.toFixed() + props.y.toUpperCase()); } }); +var instance3 = new Foo(0, ""); +var _instance3 = new Foo(0, ""); +var result3 = foo(0, ""); +var _result3 = foo(0, ""); +var tagged3 = tag(__makeTemplateObject(["tags ", " ", ""], ["tags ", " ", ""]), 12, ""); +var _tagged3 = tag(__makeTemplateObject(["tags ", " ", ""], ["tags ", " ", ""]), 12, ""); +var jsx3 = React.createElement(Component, { x: 12, y: "", cb: function (props) { return void (props.x.toFixed() + props.y.toUpperCase()); } }); +var _jsx3 = React.createElement(Component, { x: 12, y: "", cb: function (props) { return void (props.x.toFixed() + props.y.toUpperCase()); } }); +var result4 = stillDefaultsIfNoInference({ b: "test" }); // expect result1 type is {a: string, b: string, c: object, x: {} +var Foo2 = /** @class */ (function () { + function Foo2(a, b) { + this.a = a; + this.b = b; + } + return Foo2; +}()); +var x = new Foo2(); +x.a.x; +x.a.y; +x.b; diff --git a/tests/baselines/reference/inferPartialTypeArguments.symbols b/tests/baselines/reference/inferPartialTypeArguments.symbols new file mode 100644 index 0000000000000..8ff265d231517 --- /dev/null +++ b/tests/baselines/reference/inferPartialTypeArguments.symbols @@ -0,0 +1,268 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArguments.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(inferPartialTypeArguments.tsx, 0, 0)) + + interface Element {} +>Element : Symbol(Element, Decl(inferPartialTypeArguments.tsx, 0, 20)) +} +declare namespace React { +>React : Symbol(React, Decl(inferPartialTypeArguments.tsx, 2, 1)) + + export function createElement(x: any, p: any, ...children: any[]): JSX.Element; +>createElement : Symbol(createElement, Decl(inferPartialTypeArguments.tsx, 3, 25)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 4, 34)) +>p : Symbol(p, Decl(inferPartialTypeArguments.tsx, 4, 41)) +>children : Symbol(children, Decl(inferPartialTypeArguments.tsx, 4, 49)) +>JSX : Symbol(JSX, Decl(inferPartialTypeArguments.tsx, 0, 0)) +>Element : Symbol(JSX.Element, Decl(inferPartialTypeArguments.tsx, 0, 20)) +} + class Foo { +>Foo : Symbol(Foo, Decl(inferPartialTypeArguments.tsx, 5, 1)) +>T : Symbol(T, Decl(inferPartialTypeArguments.tsx, 6, 11)) +>U : Symbol(U, Decl(inferPartialTypeArguments.tsx, 6, 13)) + + constructor(public prop1: T, public prop2: U) {} +>prop1 : Symbol(Foo.prop1, Decl(inferPartialTypeArguments.tsx, 7, 16)) +>T : Symbol(T, Decl(inferPartialTypeArguments.tsx, 6, 11)) +>prop2 : Symbol(Foo.prop2, Decl(inferPartialTypeArguments.tsx, 7, 32)) +>U : Symbol(U, Decl(inferPartialTypeArguments.tsx, 6, 13)) +} + function foo(x: T, y: U): [T, U] { return [x, y]; } +>foo : Symbol(foo, Decl(inferPartialTypeArguments.tsx, 8, 1)) +>T : Symbol(T, Decl(inferPartialTypeArguments.tsx, 9, 14)) +>U : Symbol(U, Decl(inferPartialTypeArguments.tsx, 9, 16)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 9, 20)) +>T : Symbol(T, Decl(inferPartialTypeArguments.tsx, 9, 14)) +>y : Symbol(y, Decl(inferPartialTypeArguments.tsx, 9, 25)) +>U : Symbol(U, Decl(inferPartialTypeArguments.tsx, 9, 16)) +>T : Symbol(T, Decl(inferPartialTypeArguments.tsx, 9, 14)) +>U : Symbol(U, Decl(inferPartialTypeArguments.tsx, 9, 16)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 9, 20)) +>y : Symbol(y, Decl(inferPartialTypeArguments.tsx, 9, 25)) + + function tag(x: TemplateStringsArray, ...args: (T | U)[]) { return args; } +>tag : Symbol(tag, Decl(inferPartialTypeArguments.tsx, 9, 58)) +>T : Symbol(T, Decl(inferPartialTypeArguments.tsx, 10, 14)) +>U : Symbol(U, Decl(inferPartialTypeArguments.tsx, 10, 16)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 10, 20)) +>TemplateStringsArray : Symbol(TemplateStringsArray, Decl(lib.es5.d.ts, --, --)) +>args : Symbol(args, Decl(inferPartialTypeArguments.tsx, 10, 44)) +>T : Symbol(T, Decl(inferPartialTypeArguments.tsx, 10, 14)) +>U : Symbol(U, Decl(inferPartialTypeArguments.tsx, 10, 16)) +>args : Symbol(args, Decl(inferPartialTypeArguments.tsx, 10, 44)) + + interface ComponentProps { +>ComponentProps : Symbol(ComponentProps, Decl(inferPartialTypeArguments.tsx, 10, 81)) +>T : Symbol(T, Decl(inferPartialTypeArguments.tsx, 11, 26)) +>U : Symbol(U, Decl(inferPartialTypeArguments.tsx, 11, 28)) + + x: T; +>x : Symbol(ComponentProps.x, Decl(inferPartialTypeArguments.tsx, 11, 33)) +>T : Symbol(T, Decl(inferPartialTypeArguments.tsx, 11, 26)) + + y: U; +>y : Symbol(ComponentProps.y, Decl(inferPartialTypeArguments.tsx, 12, 9)) +>U : Symbol(U, Decl(inferPartialTypeArguments.tsx, 11, 28)) + + cb(props: this): void; +>cb : Symbol(ComponentProps.cb, Decl(inferPartialTypeArguments.tsx, 13, 9)) +>props : Symbol(props, Decl(inferPartialTypeArguments.tsx, 14, 7)) +} + function Component(x: ComponentProps) { +>Component : Symbol(Component, Decl(inferPartialTypeArguments.tsx, 15, 1)) +>T : Symbol(T, Decl(inferPartialTypeArguments.tsx, 16, 20)) +>U : Symbol(U, Decl(inferPartialTypeArguments.tsx, 16, 22)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 16, 26)) +>ComponentProps : Symbol(ComponentProps, Decl(inferPartialTypeArguments.tsx, 10, 81)) +>T : Symbol(T, Decl(inferPartialTypeArguments.tsx, 16, 20)) +>U : Symbol(U, Decl(inferPartialTypeArguments.tsx, 16, 22)) + + return ; +} + +const instance1 = new Foo(0, ""); +>instance1 : Symbol(instance1, Decl(inferPartialTypeArguments.tsx, 20, 5)) +>Foo : Symbol(Foo, Decl(inferPartialTypeArguments.tsx, 5, 1)) + +const result1 = foo(0, ""); +>result1 : Symbol(result1, Decl(inferPartialTypeArguments.tsx, 21, 5)) +>foo : Symbol(foo, Decl(inferPartialTypeArguments.tsx, 8, 1)) + +const tagged1 = tag`tags ${12} ${""}`; +>tagged1 : Symbol(tagged1, Decl(inferPartialTypeArguments.tsx, 22, 5)) +>tag : Symbol(tag, Decl(inferPartialTypeArguments.tsx, 9, 58)) + +const jsx1 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx1 : Symbol(jsx1, Decl(inferPartialTypeArguments.tsx, 23, 5)) +>Component : Symbol(Component, Decl(inferPartialTypeArguments.tsx, 15, 1)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 23, 34)) +>y : Symbol(y, Decl(inferPartialTypeArguments.tsx, 23, 41)) +>cb : Symbol(cb, Decl(inferPartialTypeArguments.tsx, 23, 46)) +>props : Symbol(props, Decl(inferPartialTypeArguments.tsx, 23, 51)) +>props.x.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) +>props.x : Symbol(ComponentProps.x, Decl(inferPartialTypeArguments.tsx, 11, 33)) +>props : Symbol(props, Decl(inferPartialTypeArguments.tsx, 23, 51)) +>x : Symbol(ComponentProps.x, Decl(inferPartialTypeArguments.tsx, 11, 33)) +>toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) +>props.y.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +>props.y : Symbol(ComponentProps.y, Decl(inferPartialTypeArguments.tsx, 12, 9)) +>props : Symbol(props, Decl(inferPartialTypeArguments.tsx, 23, 51)) +>y : Symbol(ComponentProps.y, Decl(inferPartialTypeArguments.tsx, 12, 9)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) + +const instance2 = new Foo<_, string>(0, ""); +>instance2 : Symbol(instance2, Decl(inferPartialTypeArguments.tsx, 25, 5)) +>Foo : Symbol(Foo, Decl(inferPartialTypeArguments.tsx, 5, 1)) + +const result2 = foo<_, string>(0, ""); +>result2 : Symbol(result2, Decl(inferPartialTypeArguments.tsx, 26, 5)) +>foo : Symbol(foo, Decl(inferPartialTypeArguments.tsx, 8, 1)) + +const tagged2 = tag<_, string>`tags ${12} ${""}`; +>tagged2 : Symbol(tagged2, Decl(inferPartialTypeArguments.tsx, 27, 5)) +>tag : Symbol(tag, Decl(inferPartialTypeArguments.tsx, 9, 58)) + +const jsx2 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx2 : Symbol(jsx2, Decl(inferPartialTypeArguments.tsx, 28, 5)) +>Component : Symbol(Component, Decl(inferPartialTypeArguments.tsx, 15, 1)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 28, 34)) +>y : Symbol(y, Decl(inferPartialTypeArguments.tsx, 28, 41)) +>cb : Symbol(cb, Decl(inferPartialTypeArguments.tsx, 28, 46)) +>props : Symbol(props, Decl(inferPartialTypeArguments.tsx, 28, 51)) +>props.x.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) +>props.x : Symbol(ComponentProps.x, Decl(inferPartialTypeArguments.tsx, 11, 33)) +>props : Symbol(props, Decl(inferPartialTypeArguments.tsx, 28, 51)) +>x : Symbol(ComponentProps.x, Decl(inferPartialTypeArguments.tsx, 11, 33)) +>toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) +>props.y.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +>props.y : Symbol(ComponentProps.y, Decl(inferPartialTypeArguments.tsx, 12, 9)) +>props : Symbol(props, Decl(inferPartialTypeArguments.tsx, 28, 51)) +>y : Symbol(ComponentProps.y, Decl(inferPartialTypeArguments.tsx, 12, 9)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) + +const instance3 = new Foo<_, _>(0, ""); +>instance3 : Symbol(instance3, Decl(inferPartialTypeArguments.tsx, 30, 5)) +>Foo : Symbol(Foo, Decl(inferPartialTypeArguments.tsx, 5, 1)) + +const _instance3 = new Foo(0, ""); +>_instance3 : Symbol(_instance3, Decl(inferPartialTypeArguments.tsx, 31, 5)) +>Foo : Symbol(Foo, Decl(inferPartialTypeArguments.tsx, 5, 1)) + +const result3 = foo<_, _>(0, ""); +>result3 : Symbol(result3, Decl(inferPartialTypeArguments.tsx, 32, 5)) +>foo : Symbol(foo, Decl(inferPartialTypeArguments.tsx, 8, 1)) + +const _result3 = foo(0, ""); +>_result3 : Symbol(_result3, Decl(inferPartialTypeArguments.tsx, 33, 5)) +>foo : Symbol(foo, Decl(inferPartialTypeArguments.tsx, 8, 1)) + +const tagged3 = tag<_, _>`tags ${12} ${""}`; +>tagged3 : Symbol(tagged3, Decl(inferPartialTypeArguments.tsx, 34, 5)) +>tag : Symbol(tag, Decl(inferPartialTypeArguments.tsx, 9, 58)) + +const _tagged3 = tag`tags ${12} ${""}`; +>_tagged3 : Symbol(_tagged3, Decl(inferPartialTypeArguments.tsx, 35, 5)) +>tag : Symbol(tag, Decl(inferPartialTypeArguments.tsx, 9, 58)) + +const jsx3 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx3 : Symbol(jsx3, Decl(inferPartialTypeArguments.tsx, 36, 5)) +>Component : Symbol(Component, Decl(inferPartialTypeArguments.tsx, 15, 1)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 36, 29)) +>y : Symbol(y, Decl(inferPartialTypeArguments.tsx, 36, 36)) +>cb : Symbol(cb, Decl(inferPartialTypeArguments.tsx, 36, 41)) +>props : Symbol(props, Decl(inferPartialTypeArguments.tsx, 36, 46)) +>props.x.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) +>props.x : Symbol(ComponentProps.x, Decl(inferPartialTypeArguments.tsx, 11, 33)) +>props : Symbol(props, Decl(inferPartialTypeArguments.tsx, 36, 46)) +>x : Symbol(ComponentProps.x, Decl(inferPartialTypeArguments.tsx, 11, 33)) +>toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) +>props.y.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +>props.y : Symbol(ComponentProps.y, Decl(inferPartialTypeArguments.tsx, 12, 9)) +>props : Symbol(props, Decl(inferPartialTypeArguments.tsx, 36, 46)) +>y : Symbol(ComponentProps.y, Decl(inferPartialTypeArguments.tsx, 12, 9)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) + +const _jsx3 = void (props.x.toFixed() + props.y.toUpperCase())} />; +>_jsx3 : Symbol(_jsx3, Decl(inferPartialTypeArguments.tsx, 37, 5)) +>Component : Symbol(Component, Decl(inferPartialTypeArguments.tsx, 15, 1)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 37, 24)) +>y : Symbol(y, Decl(inferPartialTypeArguments.tsx, 37, 31)) +>cb : Symbol(cb, Decl(inferPartialTypeArguments.tsx, 37, 36)) +>props : Symbol(props, Decl(inferPartialTypeArguments.tsx, 37, 41)) +>props.x.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) +>props.x : Symbol(ComponentProps.x, Decl(inferPartialTypeArguments.tsx, 11, 33)) +>props : Symbol(props, Decl(inferPartialTypeArguments.tsx, 37, 41)) +>x : Symbol(ComponentProps.x, Decl(inferPartialTypeArguments.tsx, 11, 33)) +>toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --)) +>props.y.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +>props.y : Symbol(ComponentProps.y, Decl(inferPartialTypeArguments.tsx, 12, 9)) +>props : Symbol(props, Decl(inferPartialTypeArguments.tsx, 37, 41)) +>y : Symbol(ComponentProps.y, Decl(inferPartialTypeArguments.tsx, 12, 9)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) + +declare function stillDefaultsIfNoInference(arg: { a?: A, b?: B, c?: C, x?: X}): { a: A, b: B, c: C, x: X }; +>stillDefaultsIfNoInference : Symbol(stillDefaultsIfNoInference, Decl(inferPartialTypeArguments.tsx, 37, 103)) +>X : Symbol(X, Decl(inferPartialTypeArguments.tsx, 39, 44)) +>A : Symbol(A, Decl(inferPartialTypeArguments.tsx, 39, 46)) +>B : Symbol(B, Decl(inferPartialTypeArguments.tsx, 39, 58)) +>C : Symbol(C, Decl(inferPartialTypeArguments.tsx, 39, 70)) +>arg : Symbol(arg, Decl(inferPartialTypeArguments.tsx, 39, 84)) +>a : Symbol(a, Decl(inferPartialTypeArguments.tsx, 39, 90)) +>A : Symbol(A, Decl(inferPartialTypeArguments.tsx, 39, 46)) +>b : Symbol(b, Decl(inferPartialTypeArguments.tsx, 39, 97)) +>B : Symbol(B, Decl(inferPartialTypeArguments.tsx, 39, 58)) +>c : Symbol(c, Decl(inferPartialTypeArguments.tsx, 39, 104)) +>C : Symbol(C, Decl(inferPartialTypeArguments.tsx, 39, 70)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 39, 111)) +>X : Symbol(X, Decl(inferPartialTypeArguments.tsx, 39, 44)) +>a : Symbol(a, Decl(inferPartialTypeArguments.tsx, 39, 122)) +>A : Symbol(A, Decl(inferPartialTypeArguments.tsx, 39, 46)) +>b : Symbol(b, Decl(inferPartialTypeArguments.tsx, 39, 128)) +>B : Symbol(B, Decl(inferPartialTypeArguments.tsx, 39, 58)) +>c : Symbol(c, Decl(inferPartialTypeArguments.tsx, 39, 134)) +>C : Symbol(C, Decl(inferPartialTypeArguments.tsx, 39, 70)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 39, 140)) +>X : Symbol(X, Decl(inferPartialTypeArguments.tsx, 39, 44)) + +const result4 = stillDefaultsIfNoInference<_, _, _, object> ({ b: "test" }); // expect result1 type is {a: string, b: string, c: object, x: {} +>result4 : Symbol(result4, Decl(inferPartialTypeArguments.tsx, 40, 5)) +>stillDefaultsIfNoInference : Symbol(stillDefaultsIfNoInference, Decl(inferPartialTypeArguments.tsx, 37, 103)) +>b : Symbol(b, Decl(inferPartialTypeArguments.tsx, 40, 62)) + +class Foo2 { +>Foo2 : Symbol(Foo2, Decl(inferPartialTypeArguments.tsx, 40, 76)) +>A : Symbol(A, Decl(inferPartialTypeArguments.tsx, 42, 11)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 42, 22)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 42, 36)) +>y : Symbol(y, Decl(inferPartialTypeArguments.tsx, 42, 46)) +>B : Symbol(B, Decl(inferPartialTypeArguments.tsx, 42, 58)) + + constructor(public a?: A, public b?: B) {} +>a : Symbol(Foo2.a, Decl(inferPartialTypeArguments.tsx, 43, 16)) +>A : Symbol(A, Decl(inferPartialTypeArguments.tsx, 42, 11)) +>b : Symbol(Foo2.b, Decl(inferPartialTypeArguments.tsx, 43, 29)) +>B : Symbol(B, Decl(inferPartialTypeArguments.tsx, 42, 58)) +} +const x = new Foo2<_, string>(); +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 45, 5)) +>Foo2 : Symbol(Foo2, Decl(inferPartialTypeArguments.tsx, 40, 76)) + +x.a.x; +>x.a.x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 42, 36)) +>x.a : Symbol(Foo2.a, Decl(inferPartialTypeArguments.tsx, 43, 16)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 45, 5)) +>a : Symbol(Foo2.a, Decl(inferPartialTypeArguments.tsx, 43, 16)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 42, 36)) + +x.a.y; +>x.a.y : Symbol(y, Decl(inferPartialTypeArguments.tsx, 42, 46)) +>x.a : Symbol(Foo2.a, Decl(inferPartialTypeArguments.tsx, 43, 16)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 45, 5)) +>a : Symbol(Foo2.a, Decl(inferPartialTypeArguments.tsx, 43, 16)) +>y : Symbol(y, Decl(inferPartialTypeArguments.tsx, 42, 46)) + +x.b; +>x.b : Symbol(Foo2.b, Decl(inferPartialTypeArguments.tsx, 43, 29)) +>x : Symbol(x, Decl(inferPartialTypeArguments.tsx, 45, 5)) +>b : Symbol(Foo2.b, Decl(inferPartialTypeArguments.tsx, 43, 29)) + diff --git a/tests/baselines/reference/inferPartialTypeArguments.types b/tests/baselines/reference/inferPartialTypeArguments.types new file mode 100644 index 0000000000000..04ccc89c1ef5e --- /dev/null +++ b/tests/baselines/reference/inferPartialTypeArguments.types @@ -0,0 +1,302 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArguments.tsx === +declare module JSX { + interface Element {} +} +declare namespace React { +>React : typeof React + + export function createElement(x: any, p: any, ...children: any[]): JSX.Element; +>createElement : (x: any, p: any, ...children: any[]) => JSX.Element +>x : any +>p : any +>children : any[] +>JSX : any +} + class Foo { +>Foo : Foo + + constructor(public prop1: T, public prop2: U) {} +>prop1 : T +>prop2 : U +} + function foo(x: T, y: U): [T, U] { return [x, y]; } +>foo : (x: T, y: U) => [T, U] +>x : T +>y : U +>[x, y] : [T, U] +>x : T +>y : U + + function tag(x: TemplateStringsArray, ...args: (T | U)[]) { return args; } +>tag : (x: TemplateStringsArray, ...args: (T | U)[]) => (T | U)[] +>x : TemplateStringsArray +>args : (T | U)[] +>args : (T | U)[] + + interface ComponentProps { + x: T; +>x : T + + y: U; +>y : U + + cb(props: this): void; +>cb : (props: this) => void +>props : this +} + function Component(x: ComponentProps) { +>Component : (x: ComponentProps) => JSX.Element +>x : ComponentProps + + return ; +> : JSX.Element +>h : any +>h : any +} + +const instance1 = new Foo(0, ""); +>instance1 : Foo +>new Foo(0, "") : Foo +>Foo : typeof Foo +>0 : 0 +>"" : "" + +const result1 = foo(0, ""); +>result1 : [number, string] +>foo(0, "") : [number, string] +>foo : (x: T, y: U) => [T, U] +>0 : 0 +>"" : "" + +const tagged1 = tag`tags ${12} ${""}`; +>tagged1 : (string | number)[] +>tag`tags ${12} ${""}` : (string | number)[] +>tag : (x: TemplateStringsArray, ...args: (T | U)[]) => (T | U)[] +>`tags ${12} ${""}` : string +>12 : 12 +>"" : "" + +const jsx1 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx1 : JSX.Element +> x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} /> : JSX.Element +>Component : (x: ComponentProps) => JSX.Element +>x : number +>12 : 12 +>y : string +>cb : (props: ComponentProps) => any +>props => void (props.x.toFixed() + props.y.toUpperCase()) : (props: ComponentProps) => any +>props : ComponentProps +>void (props.x.toFixed() + props.y.toUpperCase()) : undefined +>(props.x.toFixed() + props.y.toUpperCase()) : string +>props.x.toFixed() + props.y.toUpperCase() : string +>props.x.toFixed() : string +>props.x.toFixed : (fractionDigits?: number) => string +>props.x : number +>props : ComponentProps +>x : number +>toFixed : (fractionDigits?: number) => string +>props.y.toUpperCase() : string +>props.y.toUpperCase : () => string +>props.y : string +>props : ComponentProps +>y : string +>toUpperCase : () => string + +const instance2 = new Foo<_, string>(0, ""); +>instance2 : Foo +>new Foo<_, string>(0, "") : Foo +>Foo : typeof Foo +>0 : 0 +>"" : "" + +const result2 = foo<_, string>(0, ""); +>result2 : [number, string] +>foo<_, string>(0, "") : [number, string] +>foo : (x: T, y: U) => [T, U] +>0 : 0 +>"" : "" + +const tagged2 = tag<_, string>`tags ${12} ${""}`; +>tagged2 : (string | number)[] +>tag<_, string>`tags ${12} ${""}` : (string | number)[] +>tag : (x: TemplateStringsArray, ...args: (T | U)[]) => (T | U)[] +>`tags ${12} ${""}` : string +>12 : 12 +>"" : "" + +const jsx2 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx2 : JSX.Element +> x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} /> : JSX.Element +>Component : (x: ComponentProps) => JSX.Element +>x : number +>12 : 12 +>y : string +>cb : (props: ComponentProps) => any +>props => void (props.x.toFixed() + props.y.toUpperCase()) : (props: ComponentProps) => any +>props : ComponentProps +>void (props.x.toFixed() + props.y.toUpperCase()) : undefined +>(props.x.toFixed() + props.y.toUpperCase()) : string +>props.x.toFixed() + props.y.toUpperCase() : string +>props.x.toFixed() : string +>props.x.toFixed : (fractionDigits?: number) => string +>props.x : number +>props : ComponentProps +>x : number +>toFixed : (fractionDigits?: number) => string +>props.y.toUpperCase() : string +>props.y.toUpperCase : () => string +>props.y : string +>props : ComponentProps +>y : string +>toUpperCase : () => string + +const instance3 = new Foo<_, _>(0, ""); +>instance3 : Foo +>new Foo<_, _>(0, "") : Foo +>Foo : typeof Foo +>0 : 0 +>"" : "" + +const _instance3 = new Foo(0, ""); +>_instance3 : Foo +>new Foo(0, "") : Foo +>Foo : typeof Foo +>0 : 0 +>"" : "" + +const result3 = foo<_, _>(0, ""); +>result3 : [number, string] +>foo<_, _>(0, "") : [number, string] +>foo : (x: T, y: U) => [T, U] +>0 : 0 +>"" : "" + +const _result3 = foo(0, ""); +>_result3 : [number, string] +>foo(0, "") : [number, string] +>foo : (x: T, y: U) => [T, U] +>0 : 0 +>"" : "" + +const tagged3 = tag<_, _>`tags ${12} ${""}`; +>tagged3 : ?[] +>tag<_, _>`tags ${12} ${""}` : ?[] +>tag : (x: TemplateStringsArray, ...args: (T | U)[]) => (T | U)[] +>`tags ${12} ${""}` : string +>12 : 12 +>"" : "" + +const _tagged3 = tag`tags ${12} ${""}`; +>_tagged3 : number[] +>tag`tags ${12} ${""}` : number[] +>tag : (x: TemplateStringsArray, ...args: (T | U)[]) => (T | U)[] +>`tags ${12} ${""}` : string +>12 : 12 +>"" : "" + +const jsx3 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx3 : JSX.Element +> x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} /> : JSX.Element +>Component : (x: ComponentProps) => JSX.Element +>x : number +>12 : 12 +>y : string +>cb : (props: ComponentProps) => any +>props => void (props.x.toFixed() + props.y.toUpperCase()) : (props: ComponentProps) => any +>props : ComponentProps +>void (props.x.toFixed() + props.y.toUpperCase()) : undefined +>(props.x.toFixed() + props.y.toUpperCase()) : string +>props.x.toFixed() + props.y.toUpperCase() : string +>props.x.toFixed() : string +>props.x.toFixed : (fractionDigits?: number) => string +>props.x : number +>props : ComponentProps +>x : number +>toFixed : (fractionDigits?: number) => string +>props.y.toUpperCase() : string +>props.y.toUpperCase : () => string +>props.y : string +>props : ComponentProps +>y : string +>toUpperCase : () => string + +const _jsx3 = void (props.x.toFixed() + props.y.toUpperCase())} />; +>_jsx3 : JSX.Element +> void (props.x.toFixed() + props.y.toUpperCase())} /> : JSX.Element +>Component : (x: ComponentProps) => JSX.Element +>x : number +>12 : 12 +>y : string +>cb : (props: ComponentProps) => any +>props => void (props.x.toFixed() + props.y.toUpperCase()) : (props: ComponentProps) => any +>props : ComponentProps +>void (props.x.toFixed() + props.y.toUpperCase()) : undefined +>(props.x.toFixed() + props.y.toUpperCase()) : string +>props.x.toFixed() + props.y.toUpperCase() : string +>props.x.toFixed() : string +>props.x.toFixed : (fractionDigits?: number) => string +>props.x : number +>props : ComponentProps +>x : number +>toFixed : (fractionDigits?: number) => string +>props.y.toUpperCase() : string +>props.y.toUpperCase : () => string +>props.y : string +>props : ComponentProps +>y : string +>toUpperCase : () => string + +declare function stillDefaultsIfNoInference(arg: { a?: A, b?: B, c?: C, x?: X}): { a: A, b: B, c: C, x: X }; +>stillDefaultsIfNoInference : (arg: { a?: A; b?: B; c?: C; x?: X;}) => { a: A; b: B; c: C; x: X;} +>arg : { a?: A; b?: B; c?: C; x?: X; } +>a : A +>b : B +>c : C +>x : X +>a : A +>b : B +>c : C +>x : X + +const result4 = stillDefaultsIfNoInference<_, _, _, object> ({ b: "test" }); // expect result1 type is {a: string, b: string, c: object, x: {} +>result4 : { a: string; b: string; c: object; x: unknown; } +>stillDefaultsIfNoInference<_, _, _, object> ({ b: "test" }) : { a: string; b: string; c: object; x: unknown; } +>stillDefaultsIfNoInference : (arg: { a?: A; b?: B; c?: C; x?: X; }) => { a: A; b: B; c: C; x: X; } +>{ b: "test" } : { b: string; } +>b : string +>"test" : "test" + +class Foo2 { +>Foo2 : Foo2 +>x : string +>x : string +>y : number + + constructor(public a?: A, public b?: B) {} +>a : A +>b : B +} +const x = new Foo2<_, string>(); +>x : Foo2<{ x: string; y: number; }, string> +>new Foo2<_, string>() : Foo2<{ x: string; y: number; }, string> +>Foo2 : typeof Foo2 + +x.a.x; +>x.a.x : string +>x.a : { x: string; y: number; } +>x : Foo2<{ x: string; y: number; }, string> +>a : { x: string; y: number; } +>x : string + +x.a.y; +>x.a.y : number +>x.a : { x: string; y: number; } +>x : Foo2<{ x: string; y: number; }, string> +>a : { x: string; y: number; } +>y : number + +x.b; +>x.b : string +>x : Foo2<{ x: string; y: number; }, string> +>b : string + diff --git a/tests/baselines/reference/inferPartialTypeArgumentsErrors.errors.txt b/tests/baselines/reference/inferPartialTypeArgumentsErrors.errors.txt new file mode 100644 index 0000000000000..3f7e2e26627cf --- /dev/null +++ b/tests/baselines/reference/inferPartialTypeArgumentsErrors.errors.txt @@ -0,0 +1,38 @@ +tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsErrors.ts(2,54): error TS2322: Type '"x"' is not assignable to type '"z"'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsErrors.ts(2,59): error TS2322: Type '"y"' is not assignable to type '"z"'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsErrors.ts(7,42): error TS2344: Type '"z"' does not satisfy the constraint '"x" | "y"'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsErrors.ts(8,70): error TS2322: Type '"z"' is not assignable to type '"x" | "y"'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsErrors.ts(13,61): error TS2344: Type '"x" | "y"' does not satisfy the constraint '"x"'. + Type '"y"' is not assignable to type '"x"'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsErrors.ts(14,57): error TS2322: Type '"y"' is not assignable to type '"x"'. + + +==== tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsErrors.ts (6 errors) ==== + declare function testConstraints1(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } + const expectError1 = testConstraints1<_, "z"> ({ a: ["x", "y"] }); + ~~~ +!!! error TS2322: Type '"x"' is not assignable to type '"z"'. + ~~~ +!!! error TS2322: Type '"y"' is not assignable to type '"z"'. + + declare function testConstraints2(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } + const expectAllowed1 = testConstraints2<_, "x"> ({ a: ["x", "y"] }); // OK { a: string[], b: "x"[] } + const expectAllowed2 = testConstraints2<"x" | "y", _> ({ b: ["x"] }); // OK { a: ("x" | "y")[], b: ("x" | "y")[] } + const expectError2 = testConstraints2<_, "z"> ({ a: ["x", "y"] }); // error - `A` infers as `"x" | "y"` which `"z"` does not satisfy + ~~~ +!!! error TS2344: Type '"z"' does not satisfy the constraint '"x" | "y"'. + const expectError3 = testConstraints2<"x" | "y", _> ({ b: ["x", "y", "z"] }); // error "z" not in "x" | "y" + ~~~ +!!! error TS2322: Type '"z"' is not assignable to type '"x" | "y"'. + + declare function complexConstraints(arg: { a?: A[], b?: B[], c?: C[] }): { a: A[], b: B[], c: C[] }; + const expectAllowed4 = complexConstraints<"x" | "y" | "z", _, _> ({ a: ["x"], c: ["x", "y"] }); // OK { a: ("x" | "y" | "z")[], b: ("x" | "y" | "z")[], c: ("x" | "y")[] } + // Fails because B inferred to be "x" but that conflicts with C as "x" | "y" + const expectError4 = complexConstraints<"x" | "y" | "z", _, "x" | "y">({b: ["x"]}); + ~~~~~~~~~ +!!! error TS2344: Type '"x" | "y"' does not satisfy the constraint '"x"'. +!!! error TS2344: Type '"y"' is not assignable to type '"x"'. + const expectError5 = complexConstraints<"x", _, _>({c: ["y"]}); // error "y" does not extend "x" + ~~~ +!!! error TS2322: Type '"y"' is not assignable to type '"x"'. + \ No newline at end of file diff --git a/tests/baselines/reference/inferPartialTypeArgumentsErrors.js b/tests/baselines/reference/inferPartialTypeArgumentsErrors.js new file mode 100644 index 0000000000000..1b696d6dd3d59 --- /dev/null +++ b/tests/baselines/reference/inferPartialTypeArgumentsErrors.js @@ -0,0 +1,27 @@ +//// [inferPartialTypeArgumentsErrors.ts] +declare function testConstraints1(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +const expectError1 = testConstraints1<_, "z"> ({ a: ["x", "y"] }); + +declare function testConstraints2(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +const expectAllowed1 = testConstraints2<_, "x"> ({ a: ["x", "y"] }); // OK { a: string[], b: "x"[] } +const expectAllowed2 = testConstraints2<"x" | "y", _> ({ b: ["x"] }); // OK { a: ("x" | "y")[], b: ("x" | "y")[] } +const expectError2 = testConstraints2<_, "z"> ({ a: ["x", "y"] }); // error - `A` infers as `"x" | "y"` which `"z"` does not satisfy +const expectError3 = testConstraints2<"x" | "y", _> ({ b: ["x", "y", "z"] }); // error "z" not in "x" | "y" + +declare function complexConstraints(arg: { a?: A[], b?: B[], c?: C[] }): { a: A[], b: B[], c: C[] }; +const expectAllowed4 = complexConstraints<"x" | "y" | "z", _, _> ({ a: ["x"], c: ["x", "y"] }); // OK { a: ("x" | "y" | "z")[], b: ("x" | "y" | "z")[], c: ("x" | "y")[] } +// Fails because B inferred to be "x" but that conflicts with C as "x" | "y" +const expectError4 = complexConstraints<"x" | "y" | "z", _, "x" | "y">({b: ["x"]}); +const expectError5 = complexConstraints<"x", _, _>({c: ["y"]}); // error "y" does not extend "x" + + +//// [inferPartialTypeArgumentsErrors.js] +var expectError1 = testConstraints1({ a: ["x", "y"] }); +var expectAllowed1 = testConstraints2({ a: ["x", "y"] }); // OK { a: string[], b: "x"[] } +var expectAllowed2 = testConstraints2({ b: ["x"] }); // OK { a: ("x" | "y")[], b: ("x" | "y")[] } +var expectError2 = testConstraints2({ a: ["x", "y"] }); // error - `A` infers as `"x" | "y"` which `"z"` does not satisfy +var expectError3 = testConstraints2({ b: ["x", "y", "z"] }); // error "z" not in "x" | "y" +var expectAllowed4 = complexConstraints({ a: ["x"], c: ["x", "y"] }); // OK { a: ("x" | "y" | "z")[], b: ("x" | "y" | "z")[], c: ("x" | "y")[] } +// Fails because B inferred to be "x" but that conflicts with C as "x" | "y" +var expectError4 = complexConstraints({ b: ["x"] }); +var expectError5 = complexConstraints({ c: ["y"] }); // error "y" does not extend "x" diff --git a/tests/baselines/reference/inferPartialTypeArgumentsErrors.symbols b/tests/baselines/reference/inferPartialTypeArgumentsErrors.symbols new file mode 100644 index 0000000000000..72c331fcf39f4 --- /dev/null +++ b/tests/baselines/reference/inferPartialTypeArgumentsErrors.symbols @@ -0,0 +1,94 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsErrors.ts === +declare function testConstraints1(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +>testConstraints1 : Symbol(testConstraints1, Decl(inferPartialTypeArgumentsErrors.ts, 0, 0)) +>A : Symbol(A, Decl(inferPartialTypeArgumentsErrors.ts, 0, 34)) +>B : Symbol(B, Decl(inferPartialTypeArgumentsErrors.ts, 0, 46)) +>B : Symbol(B, Decl(inferPartialTypeArgumentsErrors.ts, 0, 46)) +>arg : Symbol(arg, Decl(inferPartialTypeArgumentsErrors.ts, 0, 65)) +>a : Symbol(a, Decl(inferPartialTypeArgumentsErrors.ts, 0, 72)) +>A : Symbol(A, Decl(inferPartialTypeArgumentsErrors.ts, 0, 34)) +>b : Symbol(b, Decl(inferPartialTypeArgumentsErrors.ts, 0, 81)) +>B : Symbol(B, Decl(inferPartialTypeArgumentsErrors.ts, 0, 46)) +>a : Symbol(a, Decl(inferPartialTypeArgumentsErrors.ts, 0, 95)) +>A : Symbol(A, Decl(inferPartialTypeArgumentsErrors.ts, 0, 34)) +>b : Symbol(b, Decl(inferPartialTypeArgumentsErrors.ts, 0, 103)) +>B : Symbol(B, Decl(inferPartialTypeArgumentsErrors.ts, 0, 46)) + +const expectError1 = testConstraints1<_, "z"> ({ a: ["x", "y"] }); +>expectError1 : Symbol(expectError1, Decl(inferPartialTypeArgumentsErrors.ts, 1, 5)) +>testConstraints1 : Symbol(testConstraints1, Decl(inferPartialTypeArgumentsErrors.ts, 0, 0)) +>a : Symbol(a, Decl(inferPartialTypeArgumentsErrors.ts, 1, 48)) + +declare function testConstraints2(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +>testConstraints2 : Symbol(testConstraints2, Decl(inferPartialTypeArgumentsErrors.ts, 1, 66)) +>A : Symbol(A, Decl(inferPartialTypeArgumentsErrors.ts, 3, 34)) +>B : Symbol(B, Decl(inferPartialTypeArgumentsErrors.ts, 3, 51)) +>A : Symbol(A, Decl(inferPartialTypeArgumentsErrors.ts, 3, 34)) +>arg : Symbol(arg, Decl(inferPartialTypeArgumentsErrors.ts, 3, 65)) +>a : Symbol(a, Decl(inferPartialTypeArgumentsErrors.ts, 3, 72)) +>A : Symbol(A, Decl(inferPartialTypeArgumentsErrors.ts, 3, 34)) +>b : Symbol(b, Decl(inferPartialTypeArgumentsErrors.ts, 3, 81)) +>B : Symbol(B, Decl(inferPartialTypeArgumentsErrors.ts, 3, 51)) +>a : Symbol(a, Decl(inferPartialTypeArgumentsErrors.ts, 3, 95)) +>A : Symbol(A, Decl(inferPartialTypeArgumentsErrors.ts, 3, 34)) +>b : Symbol(b, Decl(inferPartialTypeArgumentsErrors.ts, 3, 103)) +>B : Symbol(B, Decl(inferPartialTypeArgumentsErrors.ts, 3, 51)) + +const expectAllowed1 = testConstraints2<_, "x"> ({ a: ["x", "y"] }); // OK { a: string[], b: "x"[] } +>expectAllowed1 : Symbol(expectAllowed1, Decl(inferPartialTypeArgumentsErrors.ts, 4, 5)) +>testConstraints2 : Symbol(testConstraints2, Decl(inferPartialTypeArgumentsErrors.ts, 1, 66)) +>a : Symbol(a, Decl(inferPartialTypeArgumentsErrors.ts, 4, 50)) + +const expectAllowed2 = testConstraints2<"x" | "y", _> ({ b: ["x"] }); // OK { a: ("x" | "y")[], b: ("x" | "y")[] } +>expectAllowed2 : Symbol(expectAllowed2, Decl(inferPartialTypeArgumentsErrors.ts, 5, 5)) +>testConstraints2 : Symbol(testConstraints2, Decl(inferPartialTypeArgumentsErrors.ts, 1, 66)) +>b : Symbol(b, Decl(inferPartialTypeArgumentsErrors.ts, 5, 56)) + +const expectError2 = testConstraints2<_, "z"> ({ a: ["x", "y"] }); // error - `A` infers as `"x" | "y"` which `"z"` does not satisfy +>expectError2 : Symbol(expectError2, Decl(inferPartialTypeArgumentsErrors.ts, 6, 5)) +>testConstraints2 : Symbol(testConstraints2, Decl(inferPartialTypeArgumentsErrors.ts, 1, 66)) +>a : Symbol(a, Decl(inferPartialTypeArgumentsErrors.ts, 6, 48)) + +const expectError3 = testConstraints2<"x" | "y", _> ({ b: ["x", "y", "z"] }); // error "z" not in "x" | "y" +>expectError3 : Symbol(expectError3, Decl(inferPartialTypeArgumentsErrors.ts, 7, 5)) +>testConstraints2 : Symbol(testConstraints2, Decl(inferPartialTypeArgumentsErrors.ts, 1, 66)) +>b : Symbol(b, Decl(inferPartialTypeArgumentsErrors.ts, 7, 54)) + +declare function complexConstraints(arg: { a?: A[], b?: B[], c?: C[] }): { a: A[], b: B[], c: C[] }; +>complexConstraints : Symbol(complexConstraints, Decl(inferPartialTypeArgumentsErrors.ts, 7, 77)) +>A : Symbol(A, Decl(inferPartialTypeArgumentsErrors.ts, 9, 36)) +>B : Symbol(B, Decl(inferPartialTypeArgumentsErrors.ts, 9, 53)) +>A : Symbol(A, Decl(inferPartialTypeArgumentsErrors.ts, 9, 36)) +>C : Symbol(C, Decl(inferPartialTypeArgumentsErrors.ts, 9, 66)) +>B : Symbol(B, Decl(inferPartialTypeArgumentsErrors.ts, 9, 53)) +>arg : Symbol(arg, Decl(inferPartialTypeArgumentsErrors.ts, 9, 80)) +>a : Symbol(a, Decl(inferPartialTypeArgumentsErrors.ts, 9, 86)) +>A : Symbol(A, Decl(inferPartialTypeArgumentsErrors.ts, 9, 36)) +>b : Symbol(b, Decl(inferPartialTypeArgumentsErrors.ts, 9, 95)) +>B : Symbol(B, Decl(inferPartialTypeArgumentsErrors.ts, 9, 53)) +>c : Symbol(c, Decl(inferPartialTypeArgumentsErrors.ts, 9, 104)) +>C : Symbol(C, Decl(inferPartialTypeArgumentsErrors.ts, 9, 66)) +>a : Symbol(a, Decl(inferPartialTypeArgumentsErrors.ts, 9, 118)) +>A : Symbol(A, Decl(inferPartialTypeArgumentsErrors.ts, 9, 36)) +>b : Symbol(b, Decl(inferPartialTypeArgumentsErrors.ts, 9, 126)) +>B : Symbol(B, Decl(inferPartialTypeArgumentsErrors.ts, 9, 53)) +>c : Symbol(c, Decl(inferPartialTypeArgumentsErrors.ts, 9, 134)) +>C : Symbol(C, Decl(inferPartialTypeArgumentsErrors.ts, 9, 66)) + +const expectAllowed4 = complexConstraints<"x" | "y" | "z", _, _> ({ a: ["x"], c: ["x", "y"] }); // OK { a: ("x" | "y" | "z")[], b: ("x" | "y" | "z")[], c: ("x" | "y")[] } +>expectAllowed4 : Symbol(expectAllowed4, Decl(inferPartialTypeArgumentsErrors.ts, 10, 5)) +>complexConstraints : Symbol(complexConstraints, Decl(inferPartialTypeArgumentsErrors.ts, 7, 77)) +>a : Symbol(a, Decl(inferPartialTypeArgumentsErrors.ts, 10, 67)) +>c : Symbol(c, Decl(inferPartialTypeArgumentsErrors.ts, 10, 77)) + +// Fails because B inferred to be "x" but that conflicts with C as "x" | "y" +const expectError4 = complexConstraints<"x" | "y" | "z", _, "x" | "y">({b: ["x"]}); +>expectError4 : Symbol(expectError4, Decl(inferPartialTypeArgumentsErrors.ts, 12, 5)) +>complexConstraints : Symbol(complexConstraints, Decl(inferPartialTypeArgumentsErrors.ts, 7, 77)) +>b : Symbol(b, Decl(inferPartialTypeArgumentsErrors.ts, 12, 72)) + +const expectError5 = complexConstraints<"x", _, _>({c: ["y"]}); // error "y" does not extend "x" +>expectError5 : Symbol(expectError5, Decl(inferPartialTypeArgumentsErrors.ts, 13, 5)) +>complexConstraints : Symbol(complexConstraints, Decl(inferPartialTypeArgumentsErrors.ts, 7, 77)) +>c : Symbol(c, Decl(inferPartialTypeArgumentsErrors.ts, 13, 52)) + diff --git a/tests/baselines/reference/inferPartialTypeArgumentsErrors.types b/tests/baselines/reference/inferPartialTypeArgumentsErrors.types new file mode 100644 index 0000000000000..98c0e44e116a5 --- /dev/null +++ b/tests/baselines/reference/inferPartialTypeArgumentsErrors.types @@ -0,0 +1,109 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsErrors.ts === +declare function testConstraints1(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +>testConstraints1 : (arg?: { a?: A[]; b?: B[];}) => { a: A[]; b: B[];} +>arg : { a?: A[]; b?: B[]; } +>a : A[] +>b : B[] +>a : A[] +>b : B[] + +const expectError1 = testConstraints1<_, "z"> ({ a: ["x", "y"] }); +>expectError1 : { a: ?[]; b: "z"[]; } +>testConstraints1<_, "z"> ({ a: ["x", "y"] }) : { a: ?[]; b: "z"[]; } +>testConstraints1 : (arg?: { a?: A[]; b?: B[]; }) => { a: A[]; b: B[]; } +>{ a: ["x", "y"] } : { a: string[]; } +>a : string[] +>["x", "y"] : string[] +>"x" : "x" +>"y" : "y" + +declare function testConstraints2(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +>testConstraints2 : (arg?: { a?: A[]; b?: B[];}) => { a: A[]; b: B[];} +>arg : { a?: A[]; b?: B[]; } +>a : A[] +>b : B[] +>a : A[] +>b : B[] + +const expectAllowed1 = testConstraints2<_, "x"> ({ a: ["x", "y"] }); // OK { a: string[], b: "x"[] } +>expectAllowed1 : { a: ("x" | "y")[]; b: "x"[]; } +>testConstraints2<_, "x"> ({ a: ["x", "y"] }) : { a: ("x" | "y")[]; b: "x"[]; } +>testConstraints2 : (arg?: { a?: A[]; b?: B[]; }) => { a: A[]; b: B[]; } +>{ a: ["x", "y"] } : { a: ("x" | "y")[]; } +>a : ("x" | "y")[] +>["x", "y"] : ("x" | "y")[] +>"x" : "x" +>"y" : "y" + +const expectAllowed2 = testConstraints2<"x" | "y", _> ({ b: ["x"] }); // OK { a: ("x" | "y")[], b: ("x" | "y")[] } +>expectAllowed2 : { a: ("x" | "y")[]; b: "x"[]; } +>testConstraints2<"x" | "y", _> ({ b: ["x"] }) : { a: ("x" | "y")[]; b: "x"[]; } +>testConstraints2 : (arg?: { a?: A[]; b?: B[]; }) => { a: A[]; b: B[]; } +>{ b: ["x"] } : { b: "x"[]; } +>b : "x"[] +>["x"] : "x"[] +>"x" : "x" + +const expectError2 = testConstraints2<_, "z"> ({ a: ["x", "y"] }); // error - `A` infers as `"x" | "y"` which `"z"` does not satisfy +>expectError2 : { a: ?[]; b: "z"[]; } +>testConstraints2<_, "z"> ({ a: ["x", "y"] }) : { a: ?[]; b: "z"[]; } +>testConstraints2 : (arg?: { a?: A[]; b?: B[]; }) => { a: A[]; b: B[]; } +>{ a: ["x", "y"] } : { a: string[]; } +>a : string[] +>["x", "y"] : string[] +>"x" : "x" +>"y" : "y" + +const expectError3 = testConstraints2<"x" | "y", _> ({ b: ["x", "y", "z"] }); // error "z" not in "x" | "y" +>expectError3 : { a: ("x" | "y")[]; b: ?[]; } +>testConstraints2<"x" | "y", _> ({ b: ["x", "y", "z"] }) : { a: ("x" | "y")[]; b: ?[]; } +>testConstraints2 : (arg?: { a?: A[]; b?: B[]; }) => { a: A[]; b: B[]; } +>{ b: ["x", "y", "z"] } : { b: string[]; } +>b : string[] +>["x", "y", "z"] : string[] +>"x" : "x" +>"y" : "y" +>"z" : "z" + +declare function complexConstraints(arg: { a?: A[], b?: B[], c?: C[] }): { a: A[], b: B[], c: C[] }; +>complexConstraints : (arg: { a?: A[]; b?: B[]; c?: C[];}) => { a: A[]; b: B[]; c: C[];} +>arg : { a?: A[]; b?: B[]; c?: C[]; } +>a : A[] +>b : B[] +>c : C[] +>a : A[] +>b : B[] +>c : C[] + +const expectAllowed4 = complexConstraints<"x" | "y" | "z", _, _> ({ a: ["x"], c: ["x", "y"] }); // OK { a: ("x" | "y" | "z")[], b: ("x" | "y" | "z")[], c: ("x" | "y")[] } +>expectAllowed4 : { a: ("z" | "x" | "y")[]; b: ("z" | "x" | "y")[]; c: ("x" | "y")[]; } +>complexConstraints<"x" | "y" | "z", _, _> ({ a: ["x"], c: ["x", "y"] }) : { a: ("z" | "x" | "y")[]; b: ("z" | "x" | "y")[]; c: ("x" | "y")[]; } +>complexConstraints : (arg: { a?: A[]; b?: B[]; c?: C[]; }) => { a: A[]; b: B[]; c: C[]; } +>{ a: ["x"], c: ["x", "y"] } : { a: "x"[]; c: ("x" | "y")[]; } +>a : "x"[] +>["x"] : "x"[] +>"x" : "x" +>c : ("x" | "y")[] +>["x", "y"] : ("x" | "y")[] +>"x" : "x" +>"y" : "y" + +// Fails because B inferred to be "x" but that conflicts with C as "x" | "y" +const expectError4 = complexConstraints<"x" | "y" | "z", _, "x" | "y">({b: ["x"]}); +>expectError4 : { a: ("z" | "x" | "y")[]; b: ?[]; c: ("x" | "y")[]; } +>complexConstraints<"x" | "y" | "z", _, "x" | "y">({b: ["x"]}) : { a: ("z" | "x" | "y")[]; b: ?[]; c: ("x" | "y")[]; } +>complexConstraints : (arg: { a?: A[]; b?: B[]; c?: C[]; }) => { a: A[]; b: B[]; c: C[]; } +>{b: ["x"]} : { b: string[]; } +>b : string[] +>["x"] : string[] +>"x" : "x" + +const expectError5 = complexConstraints<"x", _, _>({c: ["y"]}); // error "y" does not extend "x" +>expectError5 : { a: "x"[]; b: ?[]; c: ?[]; } +>complexConstraints<"x", _, _>({c: ["y"]}) : { a: "x"[]; b: ?[]; c: ?[]; } +>complexConstraints : (arg: { a?: A[]; b?: B[]; c?: C[]; }) => { a: A[]; b: B[]; c: C[]; } +>{c: ["y"]} : { c: string[]; } +>c : string[] +>["y"] : string[] +>"y" : "y" + diff --git a/tests/baselines/reference/inferPartialTypeArgumentsFailureSuggestion.errors.txt b/tests/baselines/reference/inferPartialTypeArgumentsFailureSuggestion.errors.txt new file mode 100644 index 0000000000000..986d206ae7853 --- /dev/null +++ b/tests/baselines/reference/inferPartialTypeArgumentsFailureSuggestion.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsFailureSuggestion.ts(5,6): error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'. + + +==== tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsFailureSuggestion.ts (1 errors) ==== + type _ = number; + + function f(x: T extends number ? number : never) {} + + f<_>(42); + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'never'. +!!! related TS2213 tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsFailureSuggestion.ts:5:3: `_` in an expression type argument list is a placeholder type. If you meant to refer to the type named `_`, write `[_][0]` instead. + + f<[_][0]>(42); + \ No newline at end of file diff --git a/tests/baselines/reference/inferPartialTypeArgumentsFailureSuggestion.js b/tests/baselines/reference/inferPartialTypeArgumentsFailureSuggestion.js new file mode 100644 index 0000000000000..4b3904712d0d7 --- /dev/null +++ b/tests/baselines/reference/inferPartialTypeArgumentsFailureSuggestion.js @@ -0,0 +1,14 @@ +//// [inferPartialTypeArgumentsFailureSuggestion.ts] +type _ = number; + +function f(x: T extends number ? number : never) {} + +f<_>(42); + +f<[_][0]>(42); + + +//// [inferPartialTypeArgumentsFailureSuggestion.js] +function f(x) { } +f(42); +f(42); diff --git a/tests/baselines/reference/inferPartialTypeArgumentsFailureSuggestion.symbols b/tests/baselines/reference/inferPartialTypeArgumentsFailureSuggestion.symbols new file mode 100644 index 0000000000000..a5090893cd538 --- /dev/null +++ b/tests/baselines/reference/inferPartialTypeArgumentsFailureSuggestion.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsFailureSuggestion.ts === +type _ = number; +>_ : Symbol(_, Decl(inferPartialTypeArgumentsFailureSuggestion.ts, 0, 0)) + +function f(x: T extends number ? number : never) {} +>f : Symbol(f, Decl(inferPartialTypeArgumentsFailureSuggestion.ts, 0, 16)) +>T : Symbol(T, Decl(inferPartialTypeArgumentsFailureSuggestion.ts, 2, 11)) +>x : Symbol(x, Decl(inferPartialTypeArgumentsFailureSuggestion.ts, 2, 14)) +>T : Symbol(T, Decl(inferPartialTypeArgumentsFailureSuggestion.ts, 2, 11)) + +f<_>(42); +>f : Symbol(f, Decl(inferPartialTypeArgumentsFailureSuggestion.ts, 0, 16)) + +f<[_][0]>(42); +>f : Symbol(f, Decl(inferPartialTypeArgumentsFailureSuggestion.ts, 0, 16)) +>_ : Symbol(_, Decl(inferPartialTypeArgumentsFailureSuggestion.ts, 0, 0)) + diff --git a/tests/baselines/reference/inferPartialTypeArgumentsFailureSuggestion.types b/tests/baselines/reference/inferPartialTypeArgumentsFailureSuggestion.types new file mode 100644 index 0000000000000..c780242379870 --- /dev/null +++ b/tests/baselines/reference/inferPartialTypeArgumentsFailureSuggestion.types @@ -0,0 +1,18 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsFailureSuggestion.ts === +type _ = number; +>_ : number + +function f(x: T extends number ? number : never) {} +>f : (x: T extends number ? number : never) => void +>x : T extends number ? number : never + +f<_>(42); +>f<_>(42) : void +>f : (x: T extends number ? number : never) => void +>42 : 42 + +f<[_][0]>(42); +>f<[_][0]>(42) : void +>f : (x: T extends number ? number : never) => void +>42 : 42 + diff --git a/tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArguments.tsx b/tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArguments.tsx new file mode 100644 index 0000000000000..5dd050c2b2f50 --- /dev/null +++ b/tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArguments.tsx @@ -0,0 +1,50 @@ +// @jsx: react +declare module JSX { + interface Element {} +} +declare namespace React { + export function createElement(x: any, p: any, ...children: any[]): JSX.Element; +} + class Foo { + constructor(public prop1: T, public prop2: U) {} +} + function foo(x: T, y: U): [T, U] { return [x, y]; } + function tag(x: TemplateStringsArray, ...args: (T | U)[]) { return args; } + interface ComponentProps { + x: T; + y: U; + cb(props: this): void; +} + function Component(x: ComponentProps) { + return ; +} + +const instance1 = new Foo(0, ""); +const result1 = foo(0, ""); +const tagged1 = tag`tags ${12} ${""}`; +const jsx1 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + +const instance2 = new Foo<_, string>(0, ""); +const result2 = foo<_, string>(0, ""); +const tagged2 = tag<_, string>`tags ${12} ${""}`; +const jsx2 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + +const instance3 = new Foo<_, _>(0, ""); +const _instance3 = new Foo(0, ""); +const result3 = foo<_, _>(0, ""); +const _result3 = foo(0, ""); +const tagged3 = tag<_, _>`tags ${12} ${""}`; +const _tagged3 = tag`tags ${12} ${""}`; +const jsx3 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +const _jsx3 = void (props.x.toFixed() + props.y.toUpperCase())} />; + +declare function stillDefaultsIfNoInference(arg: { a?: A, b?: B, c?: C, x?: X}): { a: A, b: B, c: C, x: X }; +const result4 = stillDefaultsIfNoInference<_, _, _, object> ({ b: "test" }); // expect result1 type is {a: string, b: string, c: object, x: {} + +class Foo2 { + constructor(public a?: A, public b?: B) {} +} +const x = new Foo2<_, string>(); +x.a.x; +x.a.y; +x.b; \ No newline at end of file diff --git a/tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsErrors.ts b/tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsErrors.ts new file mode 100644 index 0000000000000..882c1dfd4cba1 --- /dev/null +++ b/tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsErrors.ts @@ -0,0 +1,14 @@ +declare function testConstraints1(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +const expectError1 = testConstraints1<_, "z"> ({ a: ["x", "y"] }); + +declare function testConstraints2(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +const expectAllowed1 = testConstraints2<_, "x"> ({ a: ["x", "y"] }); // OK { a: string[], b: "x"[] } +const expectAllowed2 = testConstraints2<"x" | "y", _> ({ b: ["x"] }); // OK { a: ("x" | "y")[], b: ("x" | "y")[] } +const expectError2 = testConstraints2<_, "z"> ({ a: ["x", "y"] }); // error - `A` infers as `"x" | "y"` which `"z"` does not satisfy +const expectError3 = testConstraints2<"x" | "y", _> ({ b: ["x", "y", "z"] }); // error "z" not in "x" | "y" + +declare function complexConstraints(arg: { a?: A[], b?: B[], c?: C[] }): { a: A[], b: B[], c: C[] }; +const expectAllowed4 = complexConstraints<"x" | "y" | "z", _, _> ({ a: ["x"], c: ["x", "y"] }); // OK { a: ("x" | "y" | "z")[], b: ("x" | "y" | "z")[], c: ("x" | "y")[] } +// Fails because B inferred to be "x" but that conflicts with C as "x" | "y" +const expectError4 = complexConstraints<"x" | "y" | "z", _, "x" | "y">({b: ["x"]}); +const expectError5 = complexConstraints<"x", _, _>({c: ["y"]}); // error "y" does not extend "x" diff --git a/tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsFailureSuggestion.ts b/tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsFailureSuggestion.ts new file mode 100644 index 0000000000000..d6412909ede07 --- /dev/null +++ b/tests/cases/conformance/types/typeParameters/typeArgumentLists/inferPartialTypeArgumentsFailureSuggestion.ts @@ -0,0 +1,7 @@ +type _ = number; + +function f(x: T extends number ? number : never) {} + +f<_>(42); + +f<[_][0]>(42);