diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ff55b99801e6f..207185fddd6b9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3754,10 +3754,9 @@ namespace ts { return typeParameterNodes; } - function lookupTypeParameterNodes(chain: Symbol[], index: number, context: NodeBuilderContext) { + function lookupTypeParameterNodes(chain: Symbol[], index: number, context: NodeBuilderContext): { typeArgumentNodes: ReadonlyArray | undefined, typeParameterNodes: ReadonlyArray | undefined } { Debug.assert(chain && 0 <= index && index < chain.length); const symbol = chain[index]; - let typeParameterNodes: ReadonlyArray | ReadonlyArray | undefined; if (context.flags & NodeBuilderFlags.WriteTypeParametersInQualifiedName && index < (chain.length - 1)) { const parentSymbol = symbol; const nextSymbol = chain[index + 1]; @@ -3765,13 +3764,13 @@ namespace ts { const params = getTypeParametersOfClassOrInterface( parentSymbol.flags & SymbolFlags.Alias ? resolveAlias(parentSymbol) : parentSymbol ); - typeParameterNodes = mapToTypeNodes(map(params, (nextSymbol as TransientSymbol).mapper!), context); + return { typeArgumentNodes: mapToTypeNodes(map(params, (nextSymbol as TransientSymbol).mapper!), context), typeParameterNodes: undefined }; } else { - typeParameterNodes = typeParametersToTypeParameterDeclarations(symbol, context); + return { typeArgumentNodes: undefined, typeParameterNodes: typeParametersToTypeParameterDeclarations(symbol, context) }; } } - return typeParameterNodes; + return { typeArgumentNodes: undefined, typeParameterNodes: undefined }; } /** @@ -3795,7 +3794,7 @@ namespace ts { if (ambientModuleSymbolRegex.test(rootName)) { // module is root, must use `ImportTypeNode` const nonRootParts = chain.length > 1 ? createAccessFromSymbolChain(chain, chain.length - 1, 1) : undefined; - const typeParameterNodes = overrideTypeArguments || lookupTypeParameterNodes(chain, 0, context); + const typeParameterNodes = overrideTypeArguments || lookupTypeParameterNodes(chain, 0, context).typeArgumentNodes; const lit = createLiteralTypeNode(createLiteral(rootName.substring(1, rootName.length - 1))); if (!nonRootParts || isEntityName(nonRootParts)) { if (nonRootParts) { @@ -3826,7 +3825,7 @@ namespace ts { } function createAccessFromSymbolChain(chain: Symbol[], index: number, stopper: number): EntityName | IndexedAccessTypeNode { - const typeParameterNodes = index === (chain.length - 1) ? overrideTypeArguments : lookupTypeParameterNodes(chain, index, context); + const { typeArgumentNodes, typeParameterNodes } = index === (chain.length - 1) ? { typeArgumentNodes: overrideTypeArguments, typeParameterNodes: undefined } : lookupTypeParameterNodes(chain, index, context); const symbol = chain[index]; if (index === 0) { @@ -3845,11 +3844,11 @@ namespace ts { return createIndexedAccessTypeNode(LHS, createLiteralTypeNode(createLiteral(symbolName))); } else { - return createIndexedAccessTypeNode(createTypeReferenceNode(LHS, typeParameterNodes as ReadonlyArray), createLiteralTypeNode(createLiteral(symbolName))); + return createIndexedAccessTypeNode(createTypeReferenceNode(LHS, typeArgumentNodes as ReadonlyArray), createLiteralTypeNode(createLiteral(symbolName))); } } - const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + const identifier = setEmitFlags(createIdentifier(symbolName, typeArgumentNodes, typeParameterNodes), EmitFlags.NoAsciiEscaping); identifier.symbol = symbol; if (index > stopper) { @@ -3876,7 +3875,7 @@ namespace ts { return createEntityNameFromSymbolChain(chain, chain.length - 1); function createEntityNameFromSymbolChain(chain: Symbol[], index: number): EntityName { - const typeParameterNodes = lookupTypeParameterNodes(chain, index, context); + const { typeArgumentNodes, typeParameterNodes } = lookupTypeParameterNodes(chain, index, context); const symbol = chain[index]; if (index === 0) { @@ -3886,8 +3885,7 @@ namespace ts { if (index === 0) { context.flags ^= NodeBuilderFlags.InInitialEntityName; } - - const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + const identifier = setEmitFlags(createIdentifier(symbolName, typeArgumentNodes, typeParameterNodes), EmitFlags.NoAsciiEscaping); identifier.symbol = symbol; return index > 0 ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; @@ -3900,7 +3898,8 @@ namespace ts { return createExpressionFromSymbolChain(chain, chain.length - 1); function createExpressionFromSymbolChain(chain: Symbol[], index: number): Expression { - const typeParameterNodes = lookupTypeParameterNodes(chain, index, context); + const { typeArgumentNodes, typeParameterNodes } = lookupTypeParameterNodes(chain, index, context); + const symbol = chain[index]; if (index === 0) { @@ -3913,7 +3912,7 @@ namespace ts { let firstChar = symbolName.charCodeAt(0); const canUsePropertyAccess = isIdentifierStart(firstChar, languageVersion); if (index === 0 || canUsePropertyAccess) { - const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + const identifier = setEmitFlags(createIdentifier(symbolName, typeArgumentNodes, typeParameterNodes), EmitFlags.NoAsciiEscaping); identifier.symbol = symbol; return index > 0 ? createPropertyAccess(createExpressionFromSymbolChain(chain, index - 1), identifier) : identifier; @@ -3932,7 +3931,7 @@ namespace ts { expression = createLiteral(+symbolName); } if (!expression) { - expression = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping); + expression = setEmitFlags(createIdentifier(symbolName, typeArgumentNodes, typeParameterNodes), EmitFlags.NoAsciiEscaping); expression.symbol = symbol; } return createElementAccess(createExpressionFromSymbolChain(chain, index - 1), expression); @@ -5300,17 +5299,16 @@ namespace ts { return getClassExtendsHeritageClauseElement(decl); } - function getConstructorsForTypeArguments(type: Type, typeArgumentNodes: ReadonlyArray | undefined, location: Node): Signature[] { + function getConstructorsForTypeArguments(type: Type, typeArgumentNodes: ReadonlyArray | undefined, location: Node): Signature[] { const typeArgCount = length(typeArgumentNodes); const isJavaScript = isInJavaScriptFile(location); return filter(getSignaturesOfType(type, SignatureKind.Construct), - sig => (isJavaScript || typeArgCount >= getMinTypeArgumentCount(sig.typeParameters)) && typeArgCount <= length(sig.typeParameters)); + sig => (isJavaScript || typeArgCount >= getMinTypeArgumentCount(typeArgumentNodes, sig.typeParameters)) && typeArgCount <= length(sig.typeParameters)); } - function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: ReadonlyArray | undefined, location: Node): Signature[] { + function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: ReadonlyArray | undefined, location: Node): Signature[] { const signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location); - const typeArguments = map(typeArgumentNodes, getTypeFromTypeNode); - return sameMap(signatures, sig => some(sig.typeParameters) ? getSignatureInstantiation(sig, typeArguments, isInJavaScriptFile(location)) : sig); + return sameMap(signatures, sig => some(sig.typeParameters) ? getSignatureInstantiation(sig, getTypeArgumentsFromTypeArgumentList(typeArgumentNodes, sig.typeParameters), isInJavaScriptFile(location)) : sig); } /** @@ -5382,7 +5380,7 @@ namespace ts { return type.resolvedBaseTypes = emptyArray; } const baseTypeNode = getBaseTypeNodeOfClass(type)!; - const typeArgs = typeArgumentsFromTypeReferenceNode(baseTypeNode); + forEach(baseTypeNode.typeArguments, checkTypeArgument); let baseType: Type; const originalBaseType = baseConstructorType && baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined; if (baseConstructorType.symbol && baseConstructorType.symbol.flags & SymbolFlags.Class && @@ -5390,7 +5388,7 @@ namespace ts { // When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the // class and all return the instance type of the class. There is no need for further checks and we can apply the // type arguments in the same manner as a type reference to get the same error reporting experience. - baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol, typeArgs); + baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol, baseTypeNode.typeArguments); } else if (baseConstructorType.flags & TypeFlags.Any) { baseType = baseConstructorType; @@ -5405,6 +5403,10 @@ namespace ts { return type.resolvedBaseTypes = emptyArray; } baseType = getReturnTypeOfSignature(constructors[0]); + if (!isInJavaScriptFile(baseTypeNode)) { + // Skip in JS files, as their type arguments can only be supplied via an augments tag, which will have arity errors issued via other code paths + checkTypespaceTypeArgumentsForCorrectness(baseTypeNode.typeArguments, getSignaturesOfType(baseConstructorType, SignatureKind.Construct)); + } } if (baseType === unknownType) { @@ -6153,14 +6155,14 @@ namespace ts { } const baseTypeNode = getBaseTypeNodeOfClass(classType)!; const isJavaScript = isInJavaScriptFile(baseTypeNode); - const typeArguments = typeArgumentsFromTypeReferenceNode(baseTypeNode); - const typeArgCount = length(typeArguments); const result: Signature[] = []; for (const baseSig of baseSignatures) { - const minTypeArgumentCount = getMinTypeArgumentCount(baseSig.typeParameters); + const typeArguments = typeArgumentsFromTypeReferenceNode(baseTypeNode, baseSig.typeParameters); + const typeArgCount = length(typeArguments); + const minTypeArgumentCount = getMinTypeArgumentCount(baseTypeNode.typeArguments, baseSig.typeParameters); const typeParamCount = length(baseSig.typeParameters); if (isJavaScript || typeArgCount >= minTypeArgumentCount && typeArgCount <= typeParamCount) { - const sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)!) : cloneSignature(baseSig); + const sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)) : cloneSignature(baseSig); sig.typeParameters = classType.localTypeParameters; sig.resolvedReturnType = classType; result.push(sig); @@ -7183,7 +7185,8 @@ namespace ts { * Gets the minimum number of type arguments needed to satisfy all non-optional type * parameters. */ - function getMinTypeArgumentCount(typeParameters: TypeParameter[] | undefined): number { + function getMinTypeArgumentCount(typeArguments: ReadonlyArray | undefined, typeParameters: TypeParameter[] | undefined): number { + if (some(typeArguments, isNamedTypeArgument)) return 0; let minTypeArgumentCount = 0; if (typeParameters) { for (let i = 0; i < typeParameters.length; i++) { @@ -7195,6 +7198,14 @@ namespace ts { return minTypeArgumentCount; } + function getDefaultForMissingTypeArgument(typeParameter: TypeParameter, isJavaScriptImplicitAny: boolean) { + let defaultType = getDefaultFromTypeParameter(typeParameter); + if (defaultType && isTypeIdenticalTo(defaultType, emptyObjectType) && isJavaScriptImplicitAny) { + defaultType = anyType; + } + return defaultType; + } + /** * Fill in default types for unsupplied type arguments. If `typeArguments` is undefined * when a default type is supplied, a new array will be created and returned. @@ -7221,12 +7232,10 @@ namespace ts { typeArguments[i] = getDefaultTypeArgumentType(isJavaScriptImplicitAny); } for (let i = numTypeArguments; i < numTypeParameters; i++) { - const mapper = createTypeMapper(typeParameters!, typeArguments); - let defaultType = getDefaultFromTypeParameter(typeParameters![i]); - if (isJavaScriptImplicitAny && defaultType && isTypeIdenticalTo(defaultType, emptyObjectType)) { - defaultType = anyType; - } - typeArguments[i] = defaultType ? instantiateType(defaultType, mapper) : getDefaultTypeArgumentType(isJavaScriptImplicitAny); + const defaultType = getDefaultForMissingTypeArgument(typeParameters![i], isJavaScriptImplicitAny); + typeArguments[i] = defaultType + ? instantiateType(defaultType, createTypeMapper(typeParameters!, typeArguments)) + : getDefaultTypeArgumentType(isJavaScriptImplicitAny); } typeArguments.length = typeParameters!.length; } @@ -7501,12 +7510,12 @@ namespace ts { } function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean): Signature { - typeArguments = fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript)!; + typeArguments = fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(/*typeArguments*/ undefined, signature.typeParameters), isJavascript); const instantiations = signature.instantiations || (signature.instantiations = createMap()); const id = getTypeListId(typeArguments); let instantiation = instantiations.get(id); if (!instantiation) { - instantiations.set(id, instantiation = createSignatureInstantiation(signature, typeArguments)); + instantiations.set(id, instantiation = createSignatureInstantiation(signature, typeArguments!)); } return instantiation; } @@ -7738,12 +7747,13 @@ namespace ts { /** * Get type from type-reference that reference to class or interface */ - function getTypeFromClassOrInterfaceReference(node: NodeWithTypeArguments, symbol: Symbol, typeArgs: Type[] | undefined): Type { + function getTypeFromClassOrInterfaceReference(node: NodeWithTypeArguments, symbol: Symbol, typeArgNodes: ReadonlyArray | undefined): Type { const type = getDeclaredTypeOfSymbol(getMergedSymbol(symbol)); const typeParameters = type.localTypeParameters; if (typeParameters) { const numTypeArguments = length(node.typeArguments); - const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); + // Pass `undefined` for typeArguments because no inference is done here, so even if there are named args, all args must be supplied + const minTypeArgumentCount = getMinTypeArgumentCount(/*typeArguments*/ undefined, typeParameters); const isJs = isInJavaScriptFile(node); const isJsImplicitAny = !noImplicitAny && isJs; if (!isJsImplicitAny && (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length)) { @@ -7762,9 +7772,14 @@ namespace ts { return unknownType; } } + if (!hasMatchesForAllNamedTypeArguments(typeParameters, node.typeArguments)) { + Debug.assert(issueNamedTypeParameterError(node.typeArguments!, typeParameters), "Type had mismatched named arg, but couldn't calculate an error"); + } + hasEnoughPositionalArguments(typeParameters, node.typeArguments, /*reportError*/ true); // In a type reference, the outer type parameters of the referenced class or interface are automatically // supplied as type arguments and the type reference only specifies arguments for the local type parameters // of the class or interface. + const typeArgs = getTypeArgumentsFromTypeArgumentList(typeArgNodes, typeParameters); const typeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgs, typeParameters, minTypeArgumentCount, isJs)); return createTypeReference(type, typeArguments); } @@ -7778,7 +7793,7 @@ namespace ts { const id = getTypeListId(typeArguments); let instantiation = links.instantiations!.get(id); if (!instantiation) { - links.instantiations!.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), isInJavaScriptFile(symbol.valueDeclaration))))); + links.instantiations!.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(/*typeArguments*/ undefined, typeParameters), isInJavaScriptFile(symbol.valueDeclaration))))); } return instantiation; } @@ -7788,12 +7803,13 @@ namespace ts { * references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the * declared type. Instantiations are cached using the type identities of the type arguments as the key. */ - function getTypeFromTypeAliasReference(node: NodeWithTypeArguments, symbol: Symbol, typeArguments: Type[] | undefined): Type { + function getTypeFromTypeAliasReference(node: NodeWithTypeArguments, symbol: Symbol, typeArgumentNodes: NodeArray | undefined): Type { const type = getDeclaredTypeOfSymbol(symbol); const typeParameters = getSymbolLinks(symbol).typeParameters; if (typeParameters) { const numTypeArguments = length(node.typeArguments); - const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); + // Pass `undefined` for typeArguments because no inference is done here, so even if there are named args, all args must be supplied + const minTypeArgumentCount = getMinTypeArgumentCount(/*typeArguments*/ undefined, typeParameters); if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) { error(node, minTypeArgumentCount === typeParameters.length @@ -7804,7 +7820,11 @@ namespace ts { typeParameters.length); return unknownType; } - return getTypeAliasInstantiation(symbol, typeArguments); + if (!hasMatchesForAllNamedTypeArguments(typeParameters, typeArgumentNodes)) { + Debug.assert(issueNamedTypeParameterError(typeArgumentNodes!, typeParameters), "Type had mismatched named arg, but couldn't calculate an error"); + } + hasEnoughPositionalArguments(typeParameters, typeArgumentNodes, /*reportError*/ true); + return getTypeAliasInstantiation(symbol, getTypeArgumentsFromTypeArgumentList(typeArgumentNodes, typeParameters)); } return checkNoTypeArguments(node, symbol) ? type : unknownType; } @@ -7834,8 +7854,9 @@ namespace ts { return resolveEntityName(typeReferenceName, meaning) || unknownSymbol; } - function getTypeReferenceType(node: NodeWithTypeArguments, symbol: Symbol): Type { - const typeArguments = typeArgumentsFromTypeReferenceNode(node); // Do unconditionally so we mark type arguments as referenced. + function getTypeReferenceType(node: NodeWithTypeArguments, symbol: Symbol) { + const typeArguments = node.typeArguments; + forEach(typeArguments, checkTypeArgument); if (symbol === unknownSymbol) { return unknownType; } @@ -7872,7 +7893,7 @@ namespace ts { * the symbol is a constructor function, return the inferred class type; otherwise, * the type of this reference is just the type of the value we resolved to. */ - function getJSDocTypeReference(node: NodeWithTypeArguments, symbol: Symbol, typeArguments: Type[] | undefined): Type | undefined { + function getJSDocTypeReference(node: NodeWithTypeArguments, symbol: Symbol, typeArguments: NodeArray | undefined): Type | undefined { const assignedType = getAssignedClassType(symbol); const valueType = getTypeOfSymbol(symbol); const referenceType = valueType.symbol && valueType.symbol !== symbol && !isInferredClassType(valueType) && getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments); @@ -7882,19 +7903,19 @@ namespace ts { } } - function getTypeReferenceTypeWorker(node: NodeWithTypeArguments, symbol: Symbol, typeArguments: Type[] | undefined): Type | undefined { + function getTypeReferenceTypeWorker(node: NodeWithTypeArguments, symbol: Symbol, typeArgumentNodes: NodeArray | undefined): Type | undefined { if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { if (symbol.valueDeclaration && isBinaryExpression(symbol.valueDeclaration.parent)) { - const jsdocType = getJSDocTypeReference(node, symbol, typeArguments); + const jsdocType = getJSDocTypeReference(node, symbol, typeArgumentNodes); if (jsdocType) { return jsdocType; } } - return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments); + return getTypeFromClassOrInterfaceReference(node, symbol, typeArgumentNodes); } if (symbol.flags & SymbolFlags.TypeAlias) { - return getTypeFromTypeAliasReference(node, symbol, typeArguments); + return getTypeFromTypeAliasReference(node, symbol, typeArgumentNodes); } if (symbol.flags & SymbolFlags.Function && @@ -7983,8 +8004,8 @@ namespace ts { case "Object": if (typeArgs && typeArgs.length === 2) { if (isJSDocIndexSignature(node)) { - const indexed = getTypeFromTypeNode(typeArgs[0]); - const target = getTypeFromTypeNode(typeArgs[1]); + const indexed = getTypeFromTypeNode(typeArgs[0] as TypeNode); + const target = getTypeFromTypeNode(typeArgs[1] as TypeNode); const index = createIndexInfo(target, /*isReadonly*/ false); return createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, indexed === stringType ? index : undefined, indexed === numberType ? index : undefined); } @@ -8023,8 +8044,8 @@ namespace ts { return links.resolvedType; } - function typeArgumentsFromTypeReferenceNode(node: NodeWithTypeArguments): Type[] | undefined { - return map(node.typeArguments, getTypeFromTypeNode); + function typeArgumentsFromTypeReferenceNode(node: NodeWithTypeArguments, targets: NodeArray | ReadonlyArray | undefined): Type[] { + return getTypeArgumentsFromTypeArgumentList(node.typeArguments, targets); } function getTypeFromTypeQueryNode(node: TypeQueryNode): Type { @@ -9382,6 +9403,128 @@ namespace ts { return links.resolvedType; } + function getSyntheticInferType(target: TypeParameter): Type { + // This type is just used as a marker that inference must occur for these positions and should never *actually* be checked + // - getPartialInferenceResult should ensure they're always mapped out of the resulting list. + const param = createType(TypeFlags.TypeParameter) as TypeParameter; + param.target = target; + const symbol = createSymbol(SymbolFlags.TypeParameter, target.symbol.escapedName, CheckFlags.ImpliedInferDecl); + param.symbol = symbol; + symbol.declaredType = param; + return param; + } + + function getTypeParameterFromTypeParameterOrTypeParameterDeclaration(target: TypeParameter | TypeParameterDeclaration) { + let param: TypeParameter; + if (((target as Node).kind && isTypeParameterDeclaration(target as Node))) { + param = getDeclaredTypeOfTypeParameter((target as TypeParameterDeclaration).symbol); + } + else { + param = target as TypeParameter; + } + return param; + } + + function getTypeArgumentsInTypeParameterOrder(nodes: ReadonlyArray | undefined, targets: ReadonlyArray | ReadonlyArray | undefined): (TypeArgument | undefined)[] { + const results: (TypeArgument | undefined)[] = []; + const named = createMap() as UnderscoreEscapedMap; + if (nodes) { + for (const node of nodes) { + if (!isNamedTypeArgument(node)) { + results.push(node); + } + else { + named.set(node.name.escapedText, node); + } + } + } + if (named.size > 0 && targets) { + const positionalCount = results.length; + const remainingTargets = targets.slice(positionalCount); + for (const target of remainingTargets) { + const param = getTypeParameterFromTypeParameterOrTypeParameterDeclaration(target); + const targetName = param.symbol.escapedName; + const provided = named.get(targetName); + results.push(provided); // intentionally may be `undefined` + } + } + return results; + } + + function getTypeArgumentsFromTypeArgumentList( + nodes: ReadonlyArray | undefined, + targets: ReadonlyArray | ReadonlyArray | undefined, + allowInferTypes?: boolean, + ordered = getTypeArgumentsInTypeParameterOrder(nodes, targets), + ) { + const len = length(ordered); + const results = new Array(len); + for (let i = 0; i < len; i++) { + results[i] = getDefaultTypeArgumentType(isInJavaScriptFile(ordered[i])); + } + let typeParameters: TypeParameter[] | undefined; // lazily initialize for use in default mapper + for (let i = 0; i < len; i++) { + const node = ordered[i]; + const target = targets && targets[i]; + if (!node && target) { + const param = getTypeParameterFromTypeParameterOrTypeParameterDeclaration(target); + if (allowInferTypes) { + results[i] = getSyntheticInferType(param); + } + else { + const defaultType = getDefaultForMissingTypeArgument(param, isInJavaScriptFile(node)); + if (defaultType) { + if (!typeParameters) { + typeParameters = map(targets, getTypeParameterFromTypeParameterOrTypeParameterDeclaration); + } + results[i] = instantiateType(defaultType, createTypeMapper(typeParameters!, results)); + } + else { + // This case is an error case, which should have an error issued by `hasEnoughPositionalArguments` + results[i] = getBaseConstraintOfType(param) || emptyObjectType; + } + } + } + else if (node) { + results[i] = isNamedTypeArgument(node) ? getTypeFromTypeNode(node.type) : getTypeFromTypeNode(node); + } + else { + return Debug.fail("Discovered an `undefined` within a type parameter list"); + } + } + + return results; + } + + function checkTypeArgument(node: TypeArgument): void { + getTypeFromTypeNode(isNamedTypeArgument(node) ? node.type : node); // return type unneeded - used to setup caches and mark referenced-ness + } + + function hasEnoughPositionalArguments(params: ReadonlyArray, typeArgumentNodes: NodeArray | undefined, reportError?: boolean): boolean { + const ordered = getTypeArgumentsInTypeParameterOrder(typeArgumentNodes, params); + const len = length(ordered); + for (let i = 0; i < len; i++) { + const arg = ordered[i]; + if (!arg && !getDefaultForMissingTypeArgument(params[i], isInJavaScriptFile(typeArgumentNodes![0]))) { + if (reportError && produceDiagnostics) { + diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(typeArgumentNodes![0]), typeArgumentNodes!, Diagnostics.No_value_provided_for_required_type_argument_0, symbolName(params[i].symbol))); + } + return false; + } + } + return true; + } + + function checkTypespaceTypeArgumentsForCorrectness(nodes: NodeArray | undefined, signatures: ReadonlyArray) { + if (!length(nodes)) return; + for (const sig of signatures) { + if (hasCorrectTypeArgumentArity(sig, nodes) && hasMatchesForAllNamedTypeArguments(sig.typeParameters, nodes) && hasEnoughPositionalArguments(sig.typeParameters!, nodes)) { + return; + } + } + issueTypeArgumentArityError(nodes![0], signatures, nodes!, /*includePositionalError*/ true); + } + function getTypeFromTypeNode(node: TypeNode): Type { switch (node.kind) { case SyntaxKind.AnyKeyword: @@ -15554,8 +15697,8 @@ namespace ts { signatures = cachedResolved; } else if (!cachedResolved) { - links.resolvedSignatures.set(cacheKey, resolvingSignaturesArray); - links.resolvedSignatures.set(cacheKey, signatures = instantiateJsxSignatures(context, signatures)); + links.resolvedSignatures.set(cacheKey, resolvingSignaturesArray); + links.resolvedSignatures.set(cacheKey, signatures = instantiateJsxSignatures(context, signatures)); } return getUnionType(map(signatures, ctor ? t => getJsxPropsTypeFromClassType(t, isJs, context, /*reportErrors*/ false) : t => getJsxPropsTypeFromCallSignature(t, context)), UnionReduction.None); @@ -15606,7 +15749,7 @@ namespace ts { const hostClassType = getReturnTypeOfSignature(sig); apparentAttributesType = intersectTypes( typeParams - ? createTypeReference(intrinsicClassAttribs, fillMissingTypeArguments([hostClassType], typeParams, getMinTypeArgumentCount(typeParams), isJs)) + ? createTypeReference(intrinsicClassAttribs, fillMissingTypeArguments([hostClassType], typeParams, getMinTypeArgumentCount(/*typeArguments*/ undefined, typeParams), isJs)) : intrinsicClassAttribs, apparentAttributesType ); @@ -16325,16 +16468,16 @@ namespace ts { const instantiatedSignatures = []; let candidateForTypeArgumentError: Signature | undefined; let hasTypeArgumentError: boolean = !!node.typeArguments; + const isJavascript = isInJavaScriptFile(node); for (const signature of signatures) { if (signature.typeParameters) { - const isJavascript = isInJavaScriptFile(node); - const typeArgumentInstantiated = getJsxSignatureTypeArgumentInstantiation(signature, node, isJavascript, /*reportErrors*/ false); + const typeArgumentInstantiated = getJsxSignatureTypeArgumentInstantiation(signature, node, isJavascript); if (typeArgumentInstantiated) { hasTypeArgumentError = false; instantiatedSignatures.push(typeArgumentInstantiated); } else { - if (node.typeArguments && hasCorrectTypeArgumentArity(signature, node.typeArguments)) { + if (node.typeArguments && hasCorrectTypeArgumentArity(signature, node.typeArguments) && hasMatchesForAllNamedTypeArguments(signature.typeParameters, node.typeArguments)) { candidateForTypeArgumentError = signature; } const inferenceContext = createInferenceContext(signature.typeParameters, signature, /*flags*/ isJavascript ? InferenceFlags.AnyDefault : InferenceFlags.None); @@ -16348,28 +16491,40 @@ namespace ts { } if (node.typeArguments && hasTypeArgumentError) { if (candidateForTypeArgumentError) { - checkTypeArguments(candidateForTypeArgumentError, node.typeArguments, /*reportErrors*/ true); + checkTypeArgumentsWithPartialInference(candidateForTypeArgumentError, node.typeArguments, isJavascript, performJsxInferenceHandler, /*reportErrors*/ true); } // Length check to avoid issuing an arity error on length=0, the "Type argument list cannot be empty" grammar error alone is fine else if (node.typeArguments.length !== 0) { - diagnostics.add(getTypeArgumentArityError(node, signatures, node.typeArguments)); + issueTypeArgumentArityError(node, signatures, node.typeArguments); } } return instantiatedSignatures; + + function performJsxInferenceHandler(sig: Signature, context: InferenceContext) { + return inferJsxTypeArguments(sig, node, context); + } } - function getJsxSignatureTypeArgumentInstantiation(signature: Signature, node: JsxOpeningLikeElement, isJavascript: boolean, reportErrors = false) { + function getJsxSignatureTypeArgumentInstantiation(signature: Signature, node: JsxOpeningLikeElement, isJavascript: boolean) { if (!node.typeArguments) { return; } - if (!hasCorrectTypeArgumentArity(signature, node.typeArguments)) { + if (!hasCorrectTypeArgumentArity(signature, node.typeArguments) || !hasMatchesForAllNamedTypeArguments(signature.typeParameters, node.typeArguments)) { return; } - const args = checkTypeArguments(signature, node.typeArguments, reportErrors); + const args = checkTypeArgumentsWithPartialInference(signature, node.typeArguments, isJavascript, performJsxInferenceHandler, /*reportErrors*/ false); if (!args) { return; } - return getSignatureInstantiation(signature, args, isJavascript); + return getSignatureInstantiation(signature, instantiateTypes(args, impliedInferTypeConstraintMapper), isJavascript); + + function performJsxInferenceHandler(sig: Signature, context: InferenceContext) { + return inferJsxTypeArguments(sig, node, context); + } + } + + function impliedInferTypeConstraintMapper(type: Type) { + return isImpliedInferType(type) ? (getConstraintFromTypeParameter(type as TypeParameter) || emptyObjectType) : type; } function getJsxNamespaceAt(location: Node): Symbol { @@ -17667,88 +17822,31 @@ namespace ts { return -1; } - function hasCorrectArity(node: CallLikeExpression, args: ReadonlyArray, signature: Signature, signatureHelpTrailingComma = false) { - let argCount: number; // Apparent number of arguments we will have in this call - let typeArguments: NodeArray | undefined; // Type arguments (undefined if none) - let callIsIncomplete = false; // In incomplete call we want to be lenient when we have too few arguments - let spreadArgIndex = -1; - - if (isJsxOpeningLikeElement(node)) { - // The arity check will be done in "checkApplicableSignatureForJsxOpeningLikeElement". - return true; - } - - if (node.kind === SyntaxKind.TaggedTemplateExpression) { - // Even if the call is incomplete, we'll have a missing expression as our last argument, - // so we can say the count is just the arg list length - argCount = args.length; - typeArguments = undefined; - - if (node.template.kind === SyntaxKind.TemplateExpression) { - // If a tagged template expression lacks a tail literal, the call is incomplete. - // Specifically, a template only can end in a TemplateTail or a Missing literal. - const lastSpan = last(node.template.templateSpans); // we should always have at least one span. - callIsIncomplete = nodeIsMissing(lastSpan.literal) || !!lastSpan.literal.isUnterminated; - } - else { - // If the template didn't end in a backtick, or its beginning occurred right prior to EOF, - // then this might actually turn out to be a TemplateHead in the future; - // so we consider the call to be incomplete. - const templateLiteral = node.template; - Debug.assert(templateLiteral.kind === SyntaxKind.NoSubstitutionTemplateLiteral); - callIsIncomplete = !!templateLiteral.isUnterminated; - } - } - else if (node.kind === SyntaxKind.Decorator) { - typeArguments = undefined; - argCount = getEffectiveArgumentCount(node, /*args*/ undefined!, signature); - } - else { - if (!node.arguments) { - // This only happens when we have something of the form: 'new C' - Debug.assert(node.kind === SyntaxKind.NewExpression); - - return signature.minArgumentCount === 0; - } - - argCount = signatureHelpTrailingComma ? args.length + 1 : args.length; - - // If we are missing the close parenthesis, the call is incomplete. - callIsIncomplete = node.arguments.end === node.end; - - typeArguments = node.typeArguments; - spreadArgIndex = getSpreadArgumentIndex(args); - } - - if (!hasCorrectTypeArgumentArity(signature, typeArguments)) { - return false; - } - - // If a spread argument is present, check that it corresponds to a rest parameter or at least that it's in the valid range. - if (spreadArgIndex >= 0) { - return isRestParameterIndex(signature, spreadArgIndex) || - signature.minArgumentCount <= spreadArgIndex && spreadArgIndex < signature.parameters.length; - } - - // Too many arguments implies incorrect arity. - if (!signature.hasRestParameter && argCount > signature.parameters.length) { - return false; - } - - // If the call is incomplete, we should skip the lower bound check. - const hasEnoughArguments = argCount >= signature.minArgumentCount; - return callIsIncomplete || hasEnoughArguments; - } - - function hasCorrectTypeArgumentArity(signature: Signature, typeArguments: NodeArray | undefined) { + function hasCorrectTypeArgumentArity(signature: Signature, typeArguments: NodeArray | undefined) { // If the user supplied type arguments, but the number of type arguments does not match // the declared number of type parameters, the call has an incorrect arity. const numTypeParameters = length(signature.typeParameters); - const minTypeArgumentCount = getMinTypeArgumentCount(signature.typeParameters); + const minTypeArgumentCount = getMinTypeArgumentCount(typeArguments, signature.typeParameters); return !typeArguments || (typeArguments.length >= minTypeArgumentCount && typeArguments.length <= numTypeParameters); } + function hasMatchesForAllNamedTypeArguments(typeParameters: ReadonlyArray | undefined, typeArguments: NodeArray | undefined) { + if (!typeArguments) return true; + // Additionally, only select overloads where there exists a match for any named type arguments supplied + const namedArgs = filter(typeArguments, isNamedTypeArgument); + if (!length(namedArgs)) return true; + const positionalCutoff = typeArguments.length - namedArgs.length; + const validTargetSlice = typeParameters && typeParameters.slice(positionalCutoff); + for (const arg of namedArgs) { + if (!some(validTargetSlice, p => p.symbol.escapedName === arg.name.escapedText)) { + return false; + } + } + + return true; + } + // If type has a single call signature and no other members, return that signature. Otherwise, return undefined. function getSingleCallSignature(type: Type): Signature | undefined { if (type.flags & TypeFlags.Object) { @@ -17876,26 +17974,45 @@ namespace ts { return getInferredTypes(context); } - function checkTypeArguments(signature: Signature, typeArgumentNodes: ReadonlyArray, reportErrors: boolean, headMessage?: DiagnosticMessage): Type[] | false { + function checkTypeArgumentsWithPartialInference(candidate: Signature, typeArguments: ReadonlyArray, isJavascript: boolean, inferenceHadler: InferenceHandler, reportErrors: boolean, headMessage?: DiagnosticMessage) { + let typeArgumentResult = checkTypeArguments(candidate, typeArguments, reportErrors, headMessage); + if (typeArgumentResult) { + typeArgumentResult = getPartialInferenceResult(typeArgumentResult, typeArguments, candidate, isJavascript, inferenceHadler, reportErrors, headMessage); + } + return typeArgumentResult; + } + + function checkTypeArguments(signature: Signature, typeArgumentNodes: ReadonlyArray, reportErrors: boolean, headMessage?: DiagnosticMessage): Type[] | false { const isJavascript = isInJavaScriptFile(signature.declaration); - const typeParameters = signature.typeParameters!; - const typeArgumentTypes = fillMissingTypeArguments(map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript); + const typeParameters = signature.typeParameters; + const orderedTypeArgumentNodes = getTypeArgumentsInTypeParameterOrder(typeArgumentNodes, typeParameters); + const typeArgumentTypes = fillMissingTypeArguments(getTypeArgumentsFromTypeArgumentList(typeArgumentNodes, typeParameters, /*allowInferTypes*/ true, orderedTypeArgumentNodes), typeParameters, getMinTypeArgumentCount(typeArgumentNodes, typeParameters), isJavascript); + return checkTypeArgumentTypes(signature, typeArgumentTypes, orderedTypeArgumentNodes, reportErrors, headMessage); + } + + function checkTypeArgumentTypes(signature: Signature, typeArgumentTypes: Type[], orderedTypeArgumentNodes: ReadonlyArray, reportErrors: boolean, headMessage?: DiagnosticMessage): Type[] | false { + if (some(typeArgumentTypes, isImpliedInferType)) { + // Do validation once partial inference is complete + return typeArgumentTypes; + } + const typeParameters = signature.typeParameters; 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"); - const constraint = getConstraintOfTypeParameter(typeParameters[i]); + for (let i = 0; i < typeArgumentTypes.length; i++) { + Debug.assert(typeParameters![i] !== undefined, "Should not call checkTypeArguments with too many type arguments"); + // When there are named type arguments, just check compatability with the resolved base constraint () + const constraint = getConstraintOfTypeParameter(typeParameters![i]); if (!constraint) continue; const errorInfo = reportErrors && headMessage ? (() => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Type_0_does_not_satisfy_the_constraint_1)) : undefined; const typeArgumentHeadMessage = headMessage || Diagnostics.Type_0_does_not_satisfy_the_constraint_1; if (!mapper) { - mapper = createTypeMapper(typeParameters, typeArgumentTypes); + mapper = createTypeMapper(typeParameters!, typeArgumentTypes); } const typeArgument = typeArgumentTypes[i]; if (!checkTypeAssignableTo( typeArgument, getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), - reportErrors ? typeArgumentNodes[i] : undefined, + reportErrors ? orderedTypeArgumentNodes[i] : undefined, typeArgumentHeadMessage, errorInfo)) { return false; @@ -18048,7 +18165,7 @@ namespace ts { * us to match a property decorator. * Otherwise, the argument count is the length of the 'args' array. */ - function getEffectiveArgumentCount(node: CallLikeExpression, args: ReadonlyArray, signature: Signature) { + function getEffectiveArgumentCount(node: CallLikeExpression, args: ReadonlyArray | undefined, signature: Signature) { if (node.kind === SyntaxKind.Decorator) { switch (node.parent.kind) { case SyntaxKind.ClassDeclaration: @@ -18086,7 +18203,7 @@ namespace ts { } } else { - return args.length; + return !args ? 0 : args.length; } } @@ -18310,15 +18427,66 @@ namespace ts { } } - function getTypeArgumentArityError(node: Node, signatures: Signature[], typeArguments: NodeArray) { + function issueNamedTypeParameterError(typeArguments: ReadonlyArray, typeParameters: ReadonlyArray) { + let issuedError = false; + const named = filter(typeArguments, isNamedTypeArgument); + const positionalCount = typeArguments.length - named.length; + nameLoop: for (const namedArg of named) { + for (let i = 0; i < typeParameters.length; i++) { + const param = typeParameters[i]; + if (param.symbol.escapedName === namedArg.name.escapedText) { + if (i < positionalCount) { + issuedError = true; + error(namedArg.name, Diagnostics.Named_type_argument_conflicts_with_positional_type_argument_at_index_0, i); + error(typeArguments[i], Diagnostics.Positional_type_argument_conflicts_with_named_type_argument_0, idText(namedArg.name)); + } + continue nameLoop; + } + } + issuedError = true; + error(namedArg.name, Diagnostics.Signature_has_no_type_argument_named_0, idText(namedArg.name)); + } + return issuedError; + } + + function issueTypeArgumentArityError(node: Node, signatures: ReadonlyArray, typeArguments: NodeArray, includePositionalError?: boolean): void { let min = Infinity; let max = -Infinity; for (const sig of signatures) { - min = Math.min(min, getMinTypeArgumentCount(sig.typeParameters)); + min = Math.min(min, getMinTypeArgumentCount(typeArguments, sig.typeParameters)); max = Math.max(max, length(sig.typeParameters)); } const paramCount = min === max ? min : min + "-" + max; - return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length); + if (typeArguments.length >= min && typeArguments.length <= max && some(typeArguments, isNamedTypeArgument)) { + // Instead of arity, remark on the lack of a signature with matching named and positional type arguments + let issuedNameSpecificError = false; + const named = filter(typeArguments, isNamedTypeArgument); + const sigsWithTypeParameters = filter(signatures, s => !!length(s.typeParameters)); + const positionalCount = typeArguments.length - named.length; + if (sigsWithTypeParameters.length === 1) { + issuedNameSpecificError = issueNamedTypeParameterError(typeArguments, sigsWithTypeParameters[0].typeParameters!); + if (includePositionalError && !issuedNameSpecificError) { + issuedNameSpecificError = hasEnoughPositionalArguments(sigsWithTypeParameters[0].typeParameters!, typeArguments, /*reportErrors*/ true); + } + } + else { + argLoop: for (const namedArg of named) { + for (const sig of signatures) { + if (!sig.typeParameters) continue; + for (const param of sig.typeParameters) { + if (param.symbol.escapedName === namedArg.name.escapedText) continue argLoop; + } + } + issuedNameSpecificError = true; + error(namedArg.name, Diagnostics.No_signature_has_a_type_argument_named_0, idText(namedArg.name)); + } + } + if (!issuedNameSpecificError) { + diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, positionalCount > 0 ? Diagnostics.No_signature_has_all_named_type_arguments : Diagnostics.No_signature_matches_all_named_and_positional_type_arguments)); + } + return; + } + diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length)); } function resolveCall(node: CallLikeExpression, signatures: Signature[], candidatesOutArray: Signature[] | undefined, fallbackError?: DiagnosticMessage): Signature { @@ -18326,7 +18494,7 @@ namespace ts { const isDecorator = node.kind === SyntaxKind.Decorator; const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node); - let typeArguments: NodeArray | undefined; + let typeArguments: NodeArray | undefined; if (!isDecorator) { typeArguments = (node).typeArguments; @@ -18401,6 +18569,7 @@ namespace ts { // let candidateForArgumentError: Signature | undefined; let candidateForTypeArgumentError: Signature | undefined; + let hadTypeArgumentArityApplicableSignature: boolean | undefined; let result: Signature | undefined; // If we are in signature help, a trailing comma indicates that we intend to provide another argument, @@ -18445,10 +18614,10 @@ namespace ts { checkApplicableSignature(node, args!, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true); } else if (candidateForTypeArgumentError) { - checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression).typeArguments!, /*reportErrors*/ true, fallbackError); + checkTypeArgumentsWithPartialInference(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression).typeArguments!, isInJavaScriptFile(node), performStandardInferenceHandler, /*reportErrors*/ true, fallbackError); } - else if (typeArguments && every(signatures, sig => length(sig.typeParameters) !== typeArguments!.length)) { - diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments)); + else if (typeArguments && !hadTypeArgumentArityApplicableSignature) { + issueTypeArgumentArityError(node, signatures, typeArguments); } else if (args) { let min = Number.POSITIVE_INFINITY; @@ -18540,8 +18709,9 @@ namespace ts { candidate = originalCandidate; if (candidate.typeParameters) { let typeArgumentTypes: Type[]; + const isJavascript = isInJavaScriptFile(candidate.declaration); if (typeArguments) { - const typeArgumentResult = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false); + const typeArgumentResult = checkTypeArgumentsWithPartialInference(candidate, typeArguments, isJavascript, performStandardInferenceHandler, /*reportErrors*/ false); if (typeArgumentResult) { typeArgumentTypes = typeArgumentResult; } @@ -18553,7 +18723,6 @@ namespace ts { else { typeArgumentTypes = inferTypeArguments(node, candidate, args!, excludeArgument, inferenceContext!); } - const isJavascript = isInJavaScriptFile(candidate.declaration); candidate = getSignatureInstantiation(candidate, typeArgumentTypes, isJavascript); } if (!checkApplicableSignature(node, args!, candidate, relation, excludeArgument, /*reportErrors*/ false)) { @@ -18576,6 +18745,125 @@ namespace ts { return undefined; } + + function performStandardInferenceHandler(signature: Signature, context: InferenceContext) { + return inferTypeArguments(node, signature, args!, excludeArgument, context); + } + + function hasCorrectArity(node: CallLikeExpression, args: ReadonlyArray, signature: Signature, signatureHelpTrailingComma = false) { + let argCount: number; // Apparent number of arguments we will have in this call + let typeArguments: NodeArray | undefined; // Type arguments (undefined if none) + let callIsIncomplete: boolean | undefined; // In incomplete call we want to be lenient when we have too few arguments + let spreadArgIndex = -1; + + if (isJsxOpeningLikeElement(node)) { + // The arity check will be done in "checkApplicableSignatureForJsxOpeningLikeElement". + return true; + } + + if (node.kind === SyntaxKind.TaggedTemplateExpression) { + // Even if the call is incomplete, we'll have a missing expression as our last argument, + // so we can say the count is just the arg list length + argCount = args.length; + typeArguments = node.typeArguments; + + if (node.template.kind === SyntaxKind.TemplateExpression) { + // If a tagged template expression lacks a tail literal, the call is incomplete. + // Specifically, a template only can end in a TemplateTail or a Missing literal. + const lastSpan = lastOrUndefined(node.template.templateSpans); + Debug.assert(lastSpan !== undefined); // we should always have at least one span. + callIsIncomplete = nodeIsMissing(lastSpan!.literal) || !!lastSpan!.literal.isUnterminated; + } + else { + // If the template didn't end in a backtick, or its beginning occurred right prior to EOF, + // then this might actually turn out to be a TemplateHead in the future; + // so we consider the call to be incomplete. + const templateLiteral = node.template; + Debug.assert(templateLiteral.kind === SyntaxKind.NoSubstitutionTemplateLiteral); + callIsIncomplete = !!templateLiteral.isUnterminated; + } + } + else if (node.kind === SyntaxKind.Decorator) { + typeArguments = undefined; + argCount = getEffectiveArgumentCount(node, /*args*/ undefined, signature); + } + else { + if (!node.arguments) { + // This only happens when we have something of the form: 'new C' + Debug.assert(node.kind === SyntaxKind.NewExpression); + + return signature.minArgumentCount === 0; + } + + argCount = signatureHelpTrailingComma ? args.length + 1 : args.length; + + // If we are missing the close parenthesis, the call is incomplete. + callIsIncomplete = node.arguments.end === node.end; + + typeArguments = node.typeArguments; + spreadArgIndex = getSpreadArgumentIndex(args); + } + + if (!hasCorrectTypeArgumentArity(signature, typeArguments) || !hasMatchesForAllNamedTypeArguments(signature.typeParameters, typeArguments)) { + return false; + } + hadTypeArgumentArityApplicableSignature = true; + + // If a spread argument is present, check that it corresponds to a rest parameter or at least that it's in the valid range. + if (spreadArgIndex >= 0) { + return isRestParameterIndex(signature, spreadArgIndex) || + signature.minArgumentCount <= spreadArgIndex && spreadArgIndex < signature.parameters.length; + } + + // Too many arguments implies incorrect arity. + if (!signature.hasRestParameter && argCount > signature.parameters.length) { + return false; + } + + // If the call is incomplete, we should skip the lower bound check. + const hasEnoughArguments = argCount >= signature.minArgumentCount; + return callIsIncomplete || hasEnoughArguments; + } + } + + function getPartialInferenceContext(originalParams: TypeParameter[], typeArgumentResult: ReadonlyArray, uninferedInstantiation: Signature, isJavascript: boolean) { + const context = createInferenceContext(originalParams, uninferedInstantiation, isJavascript ? InferenceFlags.AnyDefault : InferenceFlags.None); + for (let i = 0; i < context.inferences.length; i++) { + const correspondingArgument = typeArgumentResult[i]; + if (!isImpliedInferType(correspondingArgument)) { + const inference = context.inferences[i]; + inference.inferredType = correspondingArgument; + inference.isFixed = true; + inference.priority = 0; + } + } + return context; + } + + type InferenceHandler = (signature: Signature, context: InferenceContext) => Type[]; + function getPartialInferenceResult(typeArgumentResult: Type[], typeArgumentNodes: ReadonlyArray, candidate: Signature, isJavascript: boolean, performInferenceHandler: InferenceHandler, reportErrors: boolean, headMessage?: DiagnosticMessage) { + if (some(typeArgumentResult, isImpliedInferType)) { + // There are implied inferences we must make, despite having type arguments + const originalParams = candidate.typeParameters; + const withOriginalArgs = map(typeArgumentResult, (r, i) => isImpliedInferType(r) ? originalParams![i] : r); + const uninferedInstantiation = getSignatureInstantiation(candidate, withOriginalArgs, isJavascript); + const context = getPartialInferenceContext(originalParams!, typeArgumentResult, uninferedInstantiation, isJavascript); + const newResults = performInferenceHandler(uninferedInstantiation, context); + // Only accept a partial inference whose results abide by the type parameter constraints + if (checkTypeArgumentTypes(candidate, newResults, getTypeArgumentsInTypeParameterOrder(typeArgumentNodes, originalParams), reportErrors, headMessage)) { + return newResults; + } + else { + // Create an inference context where all infer types have no inferences (ie, failure) and everything else maps to itself, then get the result and return it + const context = getPartialInferenceContext(originalParams!, typeArgumentResult, uninferedInstantiation, isJavascript); + return getInferredTypes(context); + } + } + return typeArgumentResult; + } + + function isImpliedInferType(type: Type) { + return type.symbol && !!(getCheckFlags(type.symbol) & CheckFlags.ImpliedInferDecl); } function getLongestCandidateIndex(candidates: Signature[], argsCount: number): number { @@ -20574,7 +20862,7 @@ namespace ts { } function getContextNode(node: Expression): Node { - if (node.kind === SyntaxKind.JsxAttributes) { + if (node.kind === SyntaxKind.JsxAttributes && node.parent.kind === SyntaxKind.JsxOpeningElement) { return node.parent.parent; // Needs to be the root JsxElement, so it encompasses the attributes _and_ the children (which are essentially part of the attributes) } return node; @@ -21473,9 +21761,9 @@ namespace ts { checkDecorators(node); } - function getEffectiveTypeArguments(node: TypeReferenceNode | ExpressionWithTypeArguments, typeParameters: TypeParameter[]): Type[] { - return fillMissingTypeArguments(map(node.typeArguments!, getTypeFromTypeNode), typeParameters, - getMinTypeArgumentCount(typeParameters), isInJavaScriptFile(node)); + function getEffectiveTypeArguments(node: TypeReferenceNode | ExpressionWithTypeArguments, typeParameters: TypeParameter[]) { + return fillMissingTypeArguments(getTypeArgumentsFromTypeArgumentList(node.typeArguments, typeParameters), typeParameters, + getMinTypeArgumentCount(node.typeArguments, typeParameters), isInJavaScriptFile(node)); } function checkTypeArgumentConstraints(node: TypeReferenceNode | ExpressionWithTypeArguments, typeParameters: TypeParameter[]): boolean { @@ -24207,7 +24495,7 @@ namespace ts { function areTypeParametersIdentical(declarations: ReadonlyArray, targetParameters: TypeParameter[]) { const maxTypeArgumentCount = length(targetParameters); - const minTypeArgumentCount = getMinTypeArgumentCount(targetParameters); + const minTypeArgumentCount = getMinTypeArgumentCount(/*typeArguments*/ undefined, targetParameters); for (const declaration of declarations) { // If this declaration has too few or too many type parameters, we report an error @@ -27603,7 +27891,7 @@ namespace ts { return checkGrammarDecoratorsAndModifiers(node) || checkGrammarIndexSignatureParameters(node); } - function checkGrammarForAtLeastOneTypeArgument(node: Node, typeArguments: NodeArray | undefined): boolean { + function checkGrammarForAtLeastOneTypeArgument(node: Node, typeArguments: NodeArray | undefined): boolean { if (typeArguments && typeArguments.length === 0) { const sourceFile = getSourceFileOfNode(node); const start = typeArguments.pos - "<".length; @@ -27613,9 +27901,37 @@ namespace ts { return false; } - function checkGrammarTypeArguments(node: Node, typeArguments: NodeArray | undefined): boolean { + function checkGrammarForNamedTypeArguments(typeArguments: NodeArray | undefined): boolean { + if (!typeArguments) return false; + let errored = false; + const nameMap = createUnderscoreEscapedMap(); + for (const arg of typeArguments) { + const isNamed = isNamedTypeArgument(arg); + const hasSeenNamedArg = !!nameMap.size; + if (hasSeenNamedArg && !isNamed) { + errored = grammarErrorOnNode(arg, Diagnostics.Positional_type_arguments_cannot_follow_named_type_arguments) || errored; + } + if (isNamed) { + const name = (arg as NamedTypeArgument).name.escapedText; + const existingValue = nameMap.get(name); + if (existingValue) { + if (typeof existingValue !== "string") { + errored = grammarErrorOnNode(existingValue.name, Diagnostics.Duplicate_identifier_0, name) || errored; + nameMap.set(name, "err"); + } + errored = grammarErrorOnNode((arg as NamedTypeArgument).name, Diagnostics.Duplicate_identifier_0, name) || errored; + continue; + } + nameMap.set(name, arg as NamedTypeArgument); + } + } + return errored; + } + + function checkGrammarTypeArguments(node: Node, typeArguments: NodeArray | undefined): boolean { return checkGrammarForDisallowedTrailingComma(typeArguments) || - checkGrammarForAtLeastOneTypeArgument(node, typeArguments); + checkGrammarForAtLeastOneTypeArgument(node, typeArguments) || + checkGrammarForNamedTypeArguments(typeArguments); } function checkGrammarForOmittedArgument(args: NodeArray | undefined): boolean { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 59007e610b4ad..fc05dfb94b1c6 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -975,6 +975,38 @@ "category": "Error", "code": 1343 }, + "Positional type arguments cannot follow named type arguments.": { + "category": "Error", + "code": 1344 + }, + "Named type argument conflicts with positional type argument at index '{0}'.": { + "category": "Error", + "code": 1345 + }, + "Positional type argument conflicts with named type argument '{0}'.": { + "category": "Error", + "code": 1346 + }, + "Signature has no type argument named '{0}'.": { + "category": "Error", + "code": 1347 + }, + "No signature has all named type arguments.": { + "category": "Error", + "code": 1348 + }, + "No signature matches all named and positional type arguments.": { + "category": "Error", + "code": 1349 + }, + "No signature has a type argument named '{0}'.": { + "category": "Error", + "code": 1350 + }, + "No value provided for required type argument '{0}'.": { + "category": "Error", + "code": 1351 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5e53605decf11..4cba39c574628 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -618,6 +618,8 @@ namespace ts { return emitCallSignature(node); case SyntaxKind.ConstructSignature: return emitConstructSignature(node); + case SyntaxKind.NamedTypeArgument: + return emitNamedTypeArgument(node); case SyntaxKind.IndexSignature: return emitIndexSignature(node); @@ -1036,7 +1038,7 @@ namespace ts { function emitIdentifier(node: Identifier) { const writeText = node.symbol ? writeSymbol : write; writeText(getTextOfNode(node, /*includeTrivia*/ false), node.symbol); - emitList(node, node.typeArguments, ListFormat.TypeParameters); // Call emitList directly since it could be an array of TypeParameterDeclarations _or_ type arguments + emitTypeParameters(node, node.typeParameters); } // @@ -1190,6 +1192,14 @@ namespace ts { popNameGenerationScope(node); } + function emitNamedTypeArgument(node: NamedTypeArgument) { + emit(node.name); + writeSpace(); + writePunctuation("="); + writeSpace(); + emit(node.type); + } + function emitIndexSignature(node: IndexSignatureDeclaration) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); @@ -2760,12 +2770,12 @@ namespace ts { emitList(parentNode, decorators, ListFormat.Decorators); } - function emitTypeArguments(parentNode: Node, typeArguments: NodeArray | undefined) { + function emitTypeArguments(parentNode: Node, typeArguments: NodeArray | undefined) { emitList(parentNode, typeArguments, ListFormat.TypeArguments); } - function emitTypeParameters(parentNode: SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration | ClassDeclaration | ClassExpression, typeParameters: NodeArray | undefined) { - if (isFunctionLike(parentNode) && parentNode.typeArguments) { // Quick info uses type arguments in place of type parameters on instantiated signatures + function emitTypeParameters(parentNode: SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration | ClassDeclaration | ClassExpression | Identifier, typeParameters: NodeArray | undefined) { + if ((isFunctionLike(parentNode) || isIdentifier(parentNode)) && parentNode.typeArguments) { // Quick info uses type arguments in place of type parameters on instantiated signatures return emitTypeArguments(parentNode, parentNode.typeArguments); } emitList(parentNode, typeParameters, ListFormat.TypeParameters); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 6085cc550c46c..977b8127770e1 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -116,26 +116,30 @@ namespace ts { export function createIdentifier(text: string): Identifier; /* @internal */ - export function createIdentifier(text: string, typeArguments: ReadonlyArray | undefined): Identifier; // tslint:disable-line unified-signatures - export function createIdentifier(text: string, typeArguments?: ReadonlyArray): Identifier { + export function createIdentifier(text: string, typeArguments: ReadonlyArray | undefined, typeParameters: ReadonlyArray | undefined): Identifier; // tslint:disable-line unified-signatures + export function createIdentifier(text: string, typeArguments?: ReadonlyArray, typeParameters?: ReadonlyArray): Identifier { const node = createSynthesizedNode(SyntaxKind.Identifier); node.escapedText = escapeLeadingUnderscores(text); node.originalKeywordKind = text ? stringToToken(text) : SyntaxKind.Unknown; node.autoGenerateFlags = GeneratedIdentifierFlags.None; node.autoGenerateId = 0; if (typeArguments) { - node.typeArguments = createNodeArray(typeArguments as ReadonlyArray); + node.typeArguments = createNodeArray(typeArguments); + } + if (typeParameters) { + node.typeParameters = createNodeArray(typeParameters); } return node; } export function updateIdentifier(node: Identifier): Identifier; /* @internal */ - export function updateIdentifier(node: Identifier, typeArguments: NodeArray | undefined): Identifier; // tslint:disable-line unified-signatures - export function updateIdentifier(node: Identifier, typeArguments?: NodeArray | undefined): Identifier { - return node.typeArguments !== typeArguments - ? updateNode(createIdentifier(idText(node), typeArguments), node) - : node; + export function updateIdentifier(node: Identifier, typeArguments: NodeArray | undefined, typeParameters: NodeArray | undefined): Identifier; // tslint:disable-line unified-signatures + export function updateIdentifier(node: Identifier, typeArguments?: NodeArray | undefined, typeParameters?: NodeArray | undefined): Identifier { + return node.typeArguments !== typeArguments || + node.typeParameters !== typeParameters + ? updateNode(createIdentifier(idText(node), typeArguments, typeParameters), node) + : node; } let nextAutoGenerateId = 0; @@ -608,6 +612,20 @@ namespace ts { return updateSignatureDeclaration(node, typeParameters, parameters, type); } + export function createNamedTypeArgument(name: string | Identifier, type: TypeNode) { + const node = createSynthesizedNode(SyntaxKind.NamedTypeArgument) as NamedTypeArgument; + node.name = asName(name); + node.type = type; + return node; + } + + export function updateNamedTypeArgument(node: NamedTypeArgument, name: Identifier, type: TypeNode) { + return node.name !== name || + node.type !== type + ? updateNode(createNamedTypeArgument(name, type), node) + : node; + } + export function createIndexSignature( decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, @@ -673,14 +691,14 @@ namespace ts { : node; } - export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: ReadonlyArray | undefined) { + export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: ReadonlyArray | undefined) { const node = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; node.typeName = asName(typeName); node.typeArguments = typeArguments && parenthesizeTypeParameters(typeArguments); return node; } - export function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined) { + export function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined) { return node.typeName !== typeName || node.typeArguments !== typeArguments ? updateNode(createTypeReferenceNode(typeName, typeArguments), node) @@ -809,7 +827,7 @@ namespace ts { : node; } - export function createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: ReadonlyArray, isTypeOf?: boolean) { + export function createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: ReadonlyArray, isTypeOf?: boolean) { const node = createSynthesizedNode(SyntaxKind.ImportType); node.argument = argument; node.qualifier = qualifier; @@ -818,7 +836,7 @@ namespace ts { return node; } - export function updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier?: EntityName, typeArguments?: ReadonlyArray, isTypeOf?: boolean) { + export function updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier?: EntityName, typeArguments?: ReadonlyArray, isTypeOf?: boolean) { return node.argument !== argument || node.qualifier !== qualifier || node.typeArguments !== typeArguments @@ -1003,7 +1021,7 @@ namespace ts { : node; } - export function createCall(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined) { + export function createCall(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined) { const node = createSynthesizedNode(SyntaxKind.CallExpression); node.expression = parenthesizeForAccess(expression); node.typeArguments = asNodeArray(typeArguments); @@ -1011,7 +1029,7 @@ namespace ts { return node; } - export function updateCall(node: CallExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray) { + export function updateCall(node: CallExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray) { return node.expression !== expression || node.typeArguments !== typeArguments || node.arguments !== argumentsArray @@ -1019,7 +1037,7 @@ namespace ts { : node; } - export function createNew(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined) { + export function createNew(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined) { const node = createSynthesizedNode(SyntaxKind.NewExpression); node.expression = parenthesizeForNew(expression); node.typeArguments = asNodeArray(typeArguments); @@ -1027,7 +1045,7 @@ namespace ts { return node; } - export function updateNew(node: NewExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined) { + export function updateNew(node: NewExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined) { return node.expression !== expression || node.typeArguments !== typeArguments || node.arguments !== argumentsArray @@ -1036,14 +1054,14 @@ namespace ts { } export function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; - export function createTaggedTemplate(tag: Expression, typeArguments: ReadonlyArray | undefined, template: TemplateLiteral): TaggedTemplateExpression; + export function createTaggedTemplate(tag: Expression, typeArguments: ReadonlyArray | undefined, template: TemplateLiteral): TaggedTemplateExpression; /** @internal */ - export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: ReadonlyArray | TemplateLiteral | undefined, template?: TemplateLiteral): TaggedTemplateExpression; - export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: ReadonlyArray | TemplateLiteral | undefined, template?: TemplateLiteral) { + export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: ReadonlyArray | TemplateLiteral | undefined, template?: TemplateLiteral): TaggedTemplateExpression; + export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: ReadonlyArray | TemplateLiteral | undefined, template?: TemplateLiteral) { const node = createSynthesizedNode(SyntaxKind.TaggedTemplateExpression); node.tag = parenthesizeForAccess(tag); if (template) { - node.typeArguments = asNodeArray(typeArgumentsOrTemplate as ReadonlyArray); + node.typeArguments = asNodeArray(typeArgumentsOrTemplate as ReadonlyArray); node.template = template; } else { @@ -1054,8 +1072,8 @@ namespace ts { } export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; - export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: ReadonlyArray | undefined, template: TemplateLiteral): TaggedTemplateExpression; - export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArgumentsOrTemplate: ReadonlyArray | TemplateLiteral | undefined, template?: TemplateLiteral) { + export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: ReadonlyArray | undefined, template: TemplateLiteral): TaggedTemplateExpression; + export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArgumentsOrTemplate: ReadonlyArray | TemplateLiteral | undefined, template?: TemplateLiteral) { return node.tag !== tag || (template ? node.typeArguments !== typeArgumentsOrTemplate || node.template !== template @@ -1425,14 +1443,14 @@ namespace ts { return createSynthesizedNode(SyntaxKind.OmittedExpression); } - export function createExpressionWithTypeArguments(typeArguments: ReadonlyArray | undefined, expression: Expression) { + export function createExpressionWithTypeArguments(typeArguments: ReadonlyArray | undefined, expression: Expression) { const node = createSynthesizedNode(SyntaxKind.ExpressionWithTypeArguments); node.expression = parenthesizeForAccess(expression); node.typeArguments = asNodeArray(typeArguments); return node; } - export function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: ReadonlyArray | undefined, expression: Expression) { + export function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: ReadonlyArray | undefined, expression: Expression) { return node.typeArguments !== typeArguments || node.expression !== expression ? updateNode(createExpressionWithTypeArguments(typeArguments, expression), node) @@ -2205,7 +2223,7 @@ namespace ts { : node; } - export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes) { + export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes) { const node = createSynthesizedNode(SyntaxKind.JsxSelfClosingElement); node.tagName = tagName; node.typeArguments = typeArguments && createNodeArray(typeArguments); @@ -2213,7 +2231,7 @@ namespace ts { return node; } - export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes) { + export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes) { return node.tagName !== tagName || node.typeArguments !== typeArguments || node.attributes !== attributes @@ -2221,7 +2239,7 @@ namespace ts { : node; } - export function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes) { + export function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes) { const node = createSynthesizedNode(SyntaxKind.JsxOpeningElement); node.tagName = tagName; node.typeArguments = typeArguments && createNodeArray(typeArguments); @@ -2229,7 +2247,7 @@ namespace ts { return node; } - export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes) { + export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes) { return node.tagName !== tagName || node.typeArguments !== typeArguments || node.attributes !== attributes @@ -4274,11 +4292,17 @@ namespace ts { return createNodeArray(sameMap(members, parenthesizeElementTypeMember)); } - export function parenthesizeTypeParameters(typeParameters: ReadonlyArray | undefined) { + export function parenthesizeTypeParameters(typeParameters: ReadonlyArray | undefined): MutableNodeArray | undefined; + export function parenthesizeTypeParameters(typeParameters: ReadonlyArray | undefined): MutableNodeArray | undefined; + export function parenthesizeTypeParameters(typeParameters: ReadonlyArray | ReadonlyArray | undefined): MutableNodeArray | MutableNodeArray | undefined { if (some(typeParameters)) { - const params: TypeNode[] = []; + const params: TypeArgument[] = []; for (let i = 0; i < typeParameters.length; ++i) { const entry = typeParameters[i]; + if (isNamedTypeArgument(entry)) { + params.push(entry); + continue; + } params.push(i === 0 && isFunctionOrConstructorTypeNode(entry) && entry.typeParameters ? createParenthesizedType(entry) : entry); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index cd89248144bb0..2cc6dcf698cf1 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -144,6 +144,9 @@ namespace ts { visitNodes(cbNode, cbNodes, (node).typeParameters) || visitNodes(cbNode, cbNodes, (node).parameters) || visitNode(cbNode, (node).type); + case SyntaxKind.NamedTypeArgument: + return visitNode(cbNode, (node).name) || + visitNode(cbNode, (node).type); case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: case SyntaxKind.Constructor: @@ -2251,7 +2254,7 @@ namespace ts { const node = createNode(SyntaxKind.TypeReference); node.typeName = parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected); if (!scanner.hasPrecedingLineBreak() && token() === SyntaxKind.LessThanToken) { - node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); + node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseNamedTypeArgumentOrType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); } return finishNode(node); } @@ -3124,6 +3127,27 @@ namespace ts { } } + function isNamedTypeArgumentStart() { + return token() === SyntaxKind.Identifier && nextToken() === SyntaxKind.EqualsToken; + } + + function parseNamedTypeArgument(): NamedTypeArgument { + const node = createNode(SyntaxKind.NamedTypeArgument) as NamedTypeArgument; + node.name = parseIdentifier(); + parseExpected(SyntaxKind.EqualsToken); + node.type = parseType(); + return finishNode(node); + } + + function parseNamedTypeArgumentOrType(): TypeArgument { + if (lookAhead(isNamedTypeArgumentStart)) { + return parseNamedTypeArgument(); + } + else { + return parseType(); + } + } + function parseType(): TypeNode { // The rules about 'yield' only apply to actual code/expression contexts. They don't // apply to 'type' contexts. So we disable these parameters here before moving on. @@ -4482,7 +4506,7 @@ namespace ts { return token() === SyntaxKind.NoSubstitutionTemplateLiteral || token() === SyntaxKind.TemplateHead; } - function parseTaggedTemplateRest(tag: LeftHandSideExpression, typeArguments: NodeArray | undefined) { + function parseTaggedTemplateRest(tag: LeftHandSideExpression, typeArguments: NodeArray | undefined) { const tagExpression = createNode(SyntaxKind.TaggedTemplateExpression, tag.pos); tagExpression.tag = tag; tagExpression.typeArguments = typeArguments; @@ -4541,7 +4565,7 @@ namespace ts { return undefined; } - const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType); + const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseNamedTypeArgumentOrType); if (!parseExpected(SyntaxKind.GreaterThanToken)) { // If it doesn't have the closing `>` then it's definitely not an type argument list. return undefined; @@ -5874,9 +5898,9 @@ namespace ts { return finishNode(node); } - function tryParseTypeArguments(): NodeArray | undefined { + function tryParseTypeArguments(): NodeArray | undefined { return token() === SyntaxKind.LessThanToken - ? parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken) + ? parseBracketedList(ParsingContext.TypeArguments, parseNamedTypeArgumentOrType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken) : undefined; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a3cdb32df0702..56e6151bd5233 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -264,6 +264,7 @@ namespace ts { SetAccessor, CallSignature, ConstructSignature, + NamedTypeArgument, IndexSignature, // Type TypePredicate, @@ -731,7 +732,8 @@ namespace ts { /*@internal*/ autoGenerateFlags?: GeneratedIdentifierFlags; // Specifies whether to auto-generate the text for an identifier. /*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name. isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace - /*@internal*/ typeArguments?: NodeArray; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics, quickinfo, and signature help. + /*@internal*/ typeArguments?: NodeArray; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics, quickinfo, and signature help. + /*@internal*/ typeParameters?: NodeArray; // Same as above, but for parameters /*@internal*/ jsdocDotPos?: number; // Identifier occurs in JSDoc-style generic: Id. } @@ -815,7 +817,7 @@ namespace ts { typeParameters?: NodeArray; parameters: NodeArray; type?: TypeNode; - /* @internal */ typeArguments?: NodeArray; // Used for quick info, replaces typeParameters for instantiated signatures + /* @internal */ typeArguments?: NodeArray; // Used for quick info, replaces typeParameters for instantiated signatures } export type SignatureDeclaration = @@ -1066,6 +1068,14 @@ namespace ts { _typeNodeBrand: any; } + export interface NamedTypeArgument extends Node { + kind: SyntaxKind.NamedTypeArgument; + name: Identifier; + type: TypeNode; + } + + export type TypeArgument = TypeNode | NamedTypeArgument; + export interface KeywordTypeNode extends TypeNode { kind: SyntaxKind.AnyKeyword | SyntaxKind.NumberKeyword @@ -1105,7 +1115,7 @@ namespace ts { } export interface NodeWithTypeArguments extends TypeNode { - typeArguments?: NodeArray; + typeArguments?: NodeArray; } export type TypeReferenceType = TypeReferenceNode | ExpressionWithTypeArguments; @@ -1709,7 +1719,7 @@ namespace ts { export interface CallExpression extends LeftHandSideExpression, Declaration { kind: SyntaxKind.CallExpression; expression: LeftHandSideExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; arguments: NodeArray; } @@ -1731,14 +1741,14 @@ namespace ts { export interface NewExpression extends PrimaryExpression, Declaration { kind: SyntaxKind.NewExpression; expression: LeftHandSideExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; arguments?: NodeArray; } export interface TaggedTemplateExpression extends MemberExpression { kind: SyntaxKind.TaggedTemplateExpression; tag: LeftHandSideExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; template: TemplateLiteral; } @@ -1795,7 +1805,7 @@ namespace ts { kind: SyntaxKind.JsxOpeningElement; parent: JsxElement; tagName: JsxTagNameExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; attributes: JsxAttributes; } @@ -1803,7 +1813,7 @@ namespace ts { export interface JsxSelfClosingElement extends PrimaryExpression { kind: SyntaxKind.JsxSelfClosingElement; tagName: JsxTagNameExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; attributes: JsxAttributes; } @@ -2900,7 +2910,7 @@ namespace ts { typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode | undefined; /* @internal */ typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker): TypeNode | undefined; // tslint:disable-line unified-signatures /** Note that the resulting nodes cannot be checked. */ - signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration & {typeArguments?: NodeArray} | undefined; + signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration & {typeArguments?: NodeArray} | undefined; /** Note that the resulting nodes cannot be checked. */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration | undefined; /** Note that the resulting nodes cannot be checked. */ @@ -3538,6 +3548,7 @@ namespace ts { ContainsStatic = 1 << 9, // Synthetic property with static constituent(s) Late = 1 << 10, // Late-bound symbol for a computed property with a dynamic name ReverseMapped = 1 << 11, // property of reverse-inferred homomorphic mapped type. + ImpliedInferDecl = 1 << 12, // Transitent symbol is for an implied `infer` type Synthetic = SyntheticProperty | SyntheticMethod } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index d25d41e6bbaff..2285d5afa9af7 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -968,7 +968,13 @@ namespace ts { return (node).elementType; } else if (node && node.kind === SyntaxKind.TypeReference) { - return singleOrUndefined((node).typeArguments); + const argumentNode = singleOrUndefined((node).typeArguments); + if (argumentNode && isNamedTypeArgument(argumentNode)) { + return argumentNode.type; + } + else { + return argumentNode; + } } else { return undefined; @@ -1505,6 +1511,7 @@ namespace ts { isIdentifier(node.typeName) && node.typeName.escapedText === "Object" && node.typeArguments && node.typeArguments.length === 2 && + node.typeArguments[1].kind !== SyntaxKind.NamedTypeArgument && (node.typeArguments[0].kind === SyntaxKind.StringKeyword || node.typeArguments[0].kind === SyntaxKind.NumberKeyword); } @@ -4930,6 +4937,10 @@ namespace ts { return node.kind === SyntaxKind.ConstructSignature; } + export function isNamedTypeArgument(node: Node): node is NamedTypeArgument { + return node.kind === SyntaxKind.NamedTypeArgument; + } + export function isIndexSignatureDeclaration(node: Node): node is IndexSignatureDeclaration { return node.kind === SyntaxKind.IndexSignature; } @@ -5787,6 +5798,10 @@ namespace ts { return isTypeNodeKind(node.kind); } + export function isTypeArgument(node: Node): node is TypeArgument { + return isTypeNodeKind(node.kind) || isNamedTypeArgument(node); + } + export function isFunctionOrConstructorTypeNode(node: Node): node is FunctionTypeNode | ConstructorTypeNode { switch (node.kind) { case SyntaxKind.FunctionType: diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 1b9853e9f860e..a4014b8c704ee 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -1,6 +1,4 @@ namespace ts { - const isTypeNodeOrTypeParameterDeclaration = or(isTypeNode, isTypeParameterDeclaration); - /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * @@ -220,7 +218,9 @@ namespace ts { // Names case SyntaxKind.Identifier: - return updateIdentifier(node, nodesVisitor((node).typeArguments, visitor, isTypeNodeOrTypeParameterDeclaration)); + return updateIdentifier(node, + nodesVisitor((node).typeArguments, visitor, isTypeArgument), + nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration)); case SyntaxKind.QualifiedName: return updateQualifiedName(node, @@ -328,6 +328,11 @@ namespace ts { nodesVisitor((node).parameters, visitor, isParameterDeclaration), visitNode((node).type, visitor, isTypeNode)); + case SyntaxKind.NamedTypeArgument: + return updateNamedTypeArgument(node, + visitNode((node).name, visitor, isIdentifier), + visitNode((node).type, visitor, isTypeNode)); + case SyntaxKind.IndexSignature: return updateIndexSignature(node, nodesVisitor((node).decorators, visitor, isDecorator), @@ -345,7 +350,7 @@ namespace ts { case SyntaxKind.TypeReference: return updateTypeReferenceNode(node, visitNode((node).typeName, visitor, isEntityName), - nodesVisitor((node).typeArguments, visitor, isTypeNode)); + nodesVisitor((node).typeArguments, visitor, isTypeArgument)); case SyntaxKind.FunctionType: return updateFunctionTypeNode(node, @@ -398,7 +403,7 @@ namespace ts { return updateImportTypeNode(node, visitNode((node).argument, visitor, isTypeNode), visitNode((node).qualifier, visitor, isEntityName), - visitNodes((node).typeArguments, visitor, isTypeNode), + visitNodes((node).typeArguments, visitor, isTypeArgument), (node).isTypeOf ); @@ -466,19 +471,19 @@ namespace ts { case SyntaxKind.CallExpression: return updateCall(node, visitNode((node).expression, visitor, isExpression), - nodesVisitor((node).typeArguments, visitor, isTypeNode), + nodesVisitor((node).typeArguments, visitor, isTypeArgument), nodesVisitor((node).arguments, visitor, isExpression)); case SyntaxKind.NewExpression: return updateNew(node, visitNode((node).expression, visitor, isExpression), - nodesVisitor((node).typeArguments, visitor, isTypeNode), + nodesVisitor((node).typeArguments, visitor, isTypeArgument), nodesVisitor((node).arguments, visitor, isExpression)); case SyntaxKind.TaggedTemplateExpression: return updateTaggedTemplate(node, visitNode((node).tag, visitor, isExpression), - visitNodes((node).typeArguments, visitor, isExpression), + visitNodes((node).typeArguments, visitor, isTypeArgument), visitNode((node).template, visitor, isTemplateLiteral)); case SyntaxKind.TypeAssertionExpression: @@ -571,7 +576,7 @@ namespace ts { case SyntaxKind.ExpressionWithTypeArguments: return updateExpressionWithTypeArguments(node, - nodesVisitor((node).typeArguments, visitor, isTypeNode), + nodesVisitor((node).typeArguments, visitor, isTypeArgument), visitNode((node).expression, visitor, isExpression)); case SyntaxKind.AsExpression: @@ -826,13 +831,13 @@ namespace ts { case SyntaxKind.JsxSelfClosingElement: return updateJsxSelfClosingElement(node, visitNode((node).tagName, visitor, isJsxTagNameExpression), - nodesVisitor((node).typeArguments, visitor, isTypeNode), + nodesVisitor((node).typeArguments, visitor, isTypeArgument), visitNode((node).attributes, visitor, isJsxAttributes)); case SyntaxKind.JsxOpeningElement: return updateJsxOpeningElement(node, visitNode((node).tagName, visitor, isJsxTagNameExpression), - nodesVisitor((node).typeArguments, visitor, isTypeNode), + nodesVisitor((node).typeArguments, visitor, isTypeArgument), visitNode((node).attributes, visitor, isJsxAttributes)); case SyntaxKind.JsxClosingElement: diff --git a/src/services/codefixes/annotateWithTypeFromJSDoc.ts b/src/services/codefixes/annotateWithTypeFromJSDoc.ts index 36664ead4a46f..d4afdd7ba8bef 100644 --- a/src/services/codefixes/annotateWithTypeFromJSDoc.ts +++ b/src/services/codefixes/annotateWithTypeFromJSDoc.ts @@ -162,7 +162,8 @@ namespace ts.codefix { /*questionToken*/ undefined, createTypeReferenceNode(node.typeArguments![0].kind === SyntaxKind.NumberKeyword ? "number" : "string", []), /*initializer*/ undefined); - const indexSignature = createTypeLiteralNode([createIndexSignature(/*decorators*/ undefined, /*modifiers*/ undefined, [index], node.typeArguments![1])]); + Debug.assert(!node.typeArguments![1] || isTypeNode(node.typeArguments![1])); + const indexSignature = createTypeLiteralNode([createIndexSignature(/*decorators*/ undefined, /*modifiers*/ undefined, [index], node.typeArguments![1] as TypeNode)]); setEmitFlags(indexSignature, EmitFlags.SingleLine); return indexSignature; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 3adc0f014b696..8aceac6423528 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -221,152 +221,153 @@ declare namespace ts { SetAccessor = 156, CallSignature = 157, ConstructSignature = 158, - IndexSignature = 159, - TypePredicate = 160, - TypeReference = 161, - FunctionType = 162, - ConstructorType = 163, - TypeQuery = 164, - TypeLiteral = 165, - ArrayType = 166, - TupleType = 167, - UnionType = 168, - IntersectionType = 169, - ConditionalType = 170, - InferType = 171, - ParenthesizedType = 172, - ThisType = 173, - TypeOperator = 174, - IndexedAccessType = 175, - MappedType = 176, - LiteralType = 177, - ImportType = 178, - ObjectBindingPattern = 179, - ArrayBindingPattern = 180, - BindingElement = 181, - ArrayLiteralExpression = 182, - ObjectLiteralExpression = 183, - PropertyAccessExpression = 184, - ElementAccessExpression = 185, - CallExpression = 186, - NewExpression = 187, - TaggedTemplateExpression = 188, - TypeAssertionExpression = 189, - ParenthesizedExpression = 190, - FunctionExpression = 191, - ArrowFunction = 192, - DeleteExpression = 193, - TypeOfExpression = 194, - VoidExpression = 195, - AwaitExpression = 196, - PrefixUnaryExpression = 197, - PostfixUnaryExpression = 198, - BinaryExpression = 199, - ConditionalExpression = 200, - TemplateExpression = 201, - YieldExpression = 202, - SpreadElement = 203, - ClassExpression = 204, - OmittedExpression = 205, - ExpressionWithTypeArguments = 206, - AsExpression = 207, - NonNullExpression = 208, - MetaProperty = 209, - TemplateSpan = 210, - SemicolonClassElement = 211, - Block = 212, - VariableStatement = 213, - EmptyStatement = 214, - ExpressionStatement = 215, - IfStatement = 216, - DoStatement = 217, - WhileStatement = 218, - ForStatement = 219, - ForInStatement = 220, - ForOfStatement = 221, - ContinueStatement = 222, - BreakStatement = 223, - ReturnStatement = 224, - WithStatement = 225, - SwitchStatement = 226, - LabeledStatement = 227, - ThrowStatement = 228, - TryStatement = 229, - DebuggerStatement = 230, - VariableDeclaration = 231, - VariableDeclarationList = 232, - FunctionDeclaration = 233, - ClassDeclaration = 234, - InterfaceDeclaration = 235, - TypeAliasDeclaration = 236, - EnumDeclaration = 237, - ModuleDeclaration = 238, - ModuleBlock = 239, - CaseBlock = 240, - NamespaceExportDeclaration = 241, - ImportEqualsDeclaration = 242, - ImportDeclaration = 243, - ImportClause = 244, - NamespaceImport = 245, - NamedImports = 246, - ImportSpecifier = 247, - ExportAssignment = 248, - ExportDeclaration = 249, - NamedExports = 250, - ExportSpecifier = 251, - MissingDeclaration = 252, - ExternalModuleReference = 253, - JsxElement = 254, - JsxSelfClosingElement = 255, - JsxOpeningElement = 256, - JsxClosingElement = 257, - JsxFragment = 258, - JsxOpeningFragment = 259, - JsxClosingFragment = 260, - JsxAttribute = 261, - JsxAttributes = 262, - JsxSpreadAttribute = 263, - JsxExpression = 264, - CaseClause = 265, - DefaultClause = 266, - HeritageClause = 267, - CatchClause = 268, - PropertyAssignment = 269, - ShorthandPropertyAssignment = 270, - SpreadAssignment = 271, - EnumMember = 272, - SourceFile = 273, - Bundle = 274, - UnparsedSource = 275, - InputFiles = 276, - JSDocTypeExpression = 277, - JSDocAllType = 278, - JSDocUnknownType = 279, - JSDocNullableType = 280, - JSDocNonNullableType = 281, - JSDocOptionalType = 282, - JSDocFunctionType = 283, - JSDocVariadicType = 284, - JSDocComment = 285, - JSDocTypeLiteral = 286, - JSDocSignature = 287, - JSDocTag = 288, - JSDocAugmentsTag = 289, - JSDocClassTag = 290, - JSDocCallbackTag = 291, - JSDocParameterTag = 292, - JSDocReturnTag = 293, - JSDocTypeTag = 294, - JSDocTemplateTag = 295, - JSDocTypedefTag = 296, - JSDocPropertyTag = 297, - SyntaxList = 298, - NotEmittedStatement = 299, - PartiallyEmittedExpression = 300, - CommaListExpression = 301, - MergeDeclarationMarker = 302, - EndOfDeclarationMarker = 303, - Count = 304, + NamedTypeArgument = 159, + IndexSignature = 160, + TypePredicate = 161, + TypeReference = 162, + FunctionType = 163, + ConstructorType = 164, + TypeQuery = 165, + TypeLiteral = 166, + ArrayType = 167, + TupleType = 168, + UnionType = 169, + IntersectionType = 170, + ConditionalType = 171, + InferType = 172, + ParenthesizedType = 173, + ThisType = 174, + TypeOperator = 175, + IndexedAccessType = 176, + MappedType = 177, + LiteralType = 178, + ImportType = 179, + ObjectBindingPattern = 180, + ArrayBindingPattern = 181, + BindingElement = 182, + ArrayLiteralExpression = 183, + ObjectLiteralExpression = 184, + PropertyAccessExpression = 185, + ElementAccessExpression = 186, + CallExpression = 187, + NewExpression = 188, + TaggedTemplateExpression = 189, + TypeAssertionExpression = 190, + ParenthesizedExpression = 191, + FunctionExpression = 192, + ArrowFunction = 193, + DeleteExpression = 194, + TypeOfExpression = 195, + VoidExpression = 196, + AwaitExpression = 197, + PrefixUnaryExpression = 198, + PostfixUnaryExpression = 199, + BinaryExpression = 200, + ConditionalExpression = 201, + TemplateExpression = 202, + YieldExpression = 203, + SpreadElement = 204, + ClassExpression = 205, + OmittedExpression = 206, + ExpressionWithTypeArguments = 207, + AsExpression = 208, + NonNullExpression = 209, + MetaProperty = 210, + TemplateSpan = 211, + SemicolonClassElement = 212, + Block = 213, + VariableStatement = 214, + EmptyStatement = 215, + ExpressionStatement = 216, + IfStatement = 217, + DoStatement = 218, + WhileStatement = 219, + ForStatement = 220, + ForInStatement = 221, + ForOfStatement = 222, + ContinueStatement = 223, + BreakStatement = 224, + ReturnStatement = 225, + WithStatement = 226, + SwitchStatement = 227, + LabeledStatement = 228, + ThrowStatement = 229, + TryStatement = 230, + DebuggerStatement = 231, + VariableDeclaration = 232, + VariableDeclarationList = 233, + FunctionDeclaration = 234, + ClassDeclaration = 235, + InterfaceDeclaration = 236, + TypeAliasDeclaration = 237, + EnumDeclaration = 238, + ModuleDeclaration = 239, + ModuleBlock = 240, + CaseBlock = 241, + NamespaceExportDeclaration = 242, + ImportEqualsDeclaration = 243, + ImportDeclaration = 244, + ImportClause = 245, + NamespaceImport = 246, + NamedImports = 247, + ImportSpecifier = 248, + ExportAssignment = 249, + ExportDeclaration = 250, + NamedExports = 251, + ExportSpecifier = 252, + MissingDeclaration = 253, + ExternalModuleReference = 254, + JsxElement = 255, + JsxSelfClosingElement = 256, + JsxOpeningElement = 257, + JsxClosingElement = 258, + JsxFragment = 259, + JsxOpeningFragment = 260, + JsxClosingFragment = 261, + JsxAttribute = 262, + JsxAttributes = 263, + JsxSpreadAttribute = 264, + JsxExpression = 265, + CaseClause = 266, + DefaultClause = 267, + HeritageClause = 268, + CatchClause = 269, + PropertyAssignment = 270, + ShorthandPropertyAssignment = 271, + SpreadAssignment = 272, + EnumMember = 273, + SourceFile = 274, + Bundle = 275, + UnparsedSource = 276, + InputFiles = 277, + JSDocTypeExpression = 278, + JSDocAllType = 279, + JSDocUnknownType = 280, + JSDocNullableType = 281, + JSDocNonNullableType = 282, + JSDocOptionalType = 283, + JSDocFunctionType = 284, + JSDocVariadicType = 285, + JSDocComment = 286, + JSDocTypeLiteral = 287, + JSDocSignature = 288, + JSDocTag = 289, + JSDocAugmentsTag = 290, + JSDocClassTag = 291, + JSDocCallbackTag = 292, + JSDocParameterTag = 293, + JSDocReturnTag = 294, + JSDocTypeTag = 295, + JSDocTemplateTag = 296, + JSDocTypedefTag = 297, + JSDocPropertyTag = 298, + SyntaxList = 299, + NotEmittedStatement = 300, + PartiallyEmittedExpression = 301, + CommaListExpression = 302, + MergeDeclarationMarker = 303, + EndOfDeclarationMarker = 304, + Count = 305, FirstAssignment = 58, LastAssignment = 70, FirstCompoundAssignment = 59, @@ -377,8 +378,8 @@ declare namespace ts { LastKeyword = 144, FirstFutureReservedWord = 108, LastFutureReservedWord = 116, - FirstTypeNode = 160, - LastTypeNode = 178, + FirstTypeNode = 161, + LastTypeNode = 179, FirstPunctuation = 17, LastPunctuation = 70, FirstToken = 0, @@ -392,10 +393,10 @@ declare namespace ts { FirstBinaryOperator = 27, LastBinaryOperator = 70, FirstNode = 145, - FirstJSDocNode = 277, - LastJSDocNode = 297, - FirstJSDocTagNode = 288, - LastJSDocTagNode = 297 + FirstJSDocNode = 278, + LastJSDocNode = 298, + FirstJSDocTagNode = 289, + LastJSDocTagNode = 298 } enum NodeFlags { None = 0, @@ -701,6 +702,12 @@ declare namespace ts { interface TypeNode extends Node { _typeNodeBrand: any; } + interface NamedTypeArgument extends Node { + kind: SyntaxKind.NamedTypeArgument; + name: Identifier; + type: TypeNode; + } + type TypeArgument = TypeNode | NamedTypeArgument; interface KeywordTypeNode extends TypeNode { kind: SyntaxKind.AnyKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.VoidKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.NullKeyword | SyntaxKind.NeverKeyword; } @@ -721,7 +728,7 @@ declare namespace ts { kind: SyntaxKind.ConstructorType; } interface NodeWithTypeArguments extends TypeNode { - typeArguments?: NodeArray; + typeArguments?: NodeArray; } type TypeReferenceType = TypeReferenceNode | ExpressionWithTypeArguments; interface TypeReferenceNode extends NodeWithTypeArguments { @@ -1033,7 +1040,7 @@ declare namespace ts { interface CallExpression extends LeftHandSideExpression, Declaration { kind: SyntaxKind.CallExpression; expression: LeftHandSideExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; arguments: NodeArray; } interface SuperCall extends CallExpression { @@ -1050,13 +1057,13 @@ declare namespace ts { interface NewExpression extends PrimaryExpression, Declaration { kind: SyntaxKind.NewExpression; expression: LeftHandSideExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; arguments?: NodeArray; } interface TaggedTemplateExpression extends MemberExpression { kind: SyntaxKind.TaggedTemplateExpression; tag: LeftHandSideExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; template: TemplateLiteral; } type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement; @@ -1096,13 +1103,13 @@ declare namespace ts { kind: SyntaxKind.JsxOpeningElement; parent: JsxElement; tagName: JsxTagNameExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; attributes: JsxAttributes; } interface JsxSelfClosingElement extends PrimaryExpression { kind: SyntaxKind.JsxSelfClosingElement; tagName: JsxTagNameExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; attributes: JsxAttributes; } interface JsxFragment extends PrimaryExpression { @@ -1814,7 +1821,7 @@ declare namespace ts { typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode | undefined; /** Note that the resulting nodes cannot be checked. */ signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): (SignatureDeclaration & { - typeArguments?: NodeArray; + typeArguments?: NodeArray; }) | undefined; /** Note that the resulting nodes cannot be checked. */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration | undefined; @@ -3250,6 +3257,7 @@ declare namespace ts { function isSetAccessorDeclaration(node: Node): node is SetAccessorDeclaration; function isCallSignatureDeclaration(node: Node): node is CallSignatureDeclaration; function isConstructSignatureDeclaration(node: Node): node is ConstructSignatureDeclaration; + function isNamedTypeArgument(node: Node): node is NamedTypeArgument; function isIndexSignatureDeclaration(node: Node): node is IndexSignatureDeclaration; function isTypePredicateNode(node: Node): node is TypePredicateNode; function isTypeReferenceNode(node: Node): node is TypeReferenceNode; @@ -3418,6 +3426,7 @@ declare namespace ts { * of a TypeNode. */ function isTypeNode(node: Node): node is TypeNode; + function isTypeArgument(node: Node): node is TypeArgument; function isFunctionOrConstructorTypeNode(node: Node): node is FunctionTypeNode | ConstructorTypeNode; function isPropertyAccessOrQualifiedName(node: Node): node is PropertyAccessExpression | QualifiedName; function isCallLikeExpression(node: Node): node is CallLikeExpression; @@ -3567,13 +3576,15 @@ declare namespace ts { function updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): CallSignatureDeclaration; function createConstructSignature(typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined): ConstructSignatureDeclaration; function updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructSignatureDeclaration; + function createNamedTypeArgument(name: string | Identifier, type: TypeNode): NamedTypeArgument; + function updateNamedTypeArgument(node: NamedTypeArgument, name: Identifier, type: TypeNode): NamedTypeArgument; function createIndexSignature(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode): IndexSignatureDeclaration; function updateIndexSignature(node: IndexSignatureDeclaration, decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode): IndexSignatureDeclaration; function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode; function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode): TypePredicateNode; function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode): TypePredicateNode; - function createTypeReferenceNode(typeName: string | EntityName, typeArguments: ReadonlyArray | undefined): TypeReferenceNode; - function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; + function createTypeReferenceNode(typeName: string | EntityName, typeArguments: ReadonlyArray | undefined): TypeReferenceNode; + function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; function createFunctionTypeNode(typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined): FunctionTypeNode; function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): FunctionTypeNode; function createConstructorTypeNode(typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined): ConstructorTypeNode; @@ -3595,8 +3606,8 @@ declare namespace ts { function updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; function createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode; function updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode; - function createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: ReadonlyArray, isTypeOf?: boolean): ImportTypeNode; - function updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier?: EntityName, typeArguments?: ReadonlyArray, isTypeOf?: boolean): ImportTypeNode; + function createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: ReadonlyArray, isTypeOf?: boolean): ImportTypeNode; + function updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier?: EntityName, typeArguments?: ReadonlyArray, isTypeOf?: boolean): ImportTypeNode; function createParenthesizedType(type: TypeNode): ParenthesizedTypeNode; function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode; function createThisTypeNode(): ThisTypeNode; @@ -3623,14 +3634,14 @@ declare namespace ts { function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression; function createElementAccess(expression: Expression, index: number | Expression): ElementAccessExpression; function updateElementAccess(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression; - function createCall(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): CallExpression; - function updateCall(node: CallExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray): CallExpression; - function createNew(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; - function updateNew(node: NewExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; + function createCall(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): CallExpression; + function updateCall(node: CallExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray): CallExpression; + function createNew(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; + function updateNew(node: NewExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; - function createTaggedTemplate(tag: Expression, typeArguments: ReadonlyArray | undefined, template: TemplateLiteral): TaggedTemplateExpression; + function createTaggedTemplate(tag: Expression, typeArguments: ReadonlyArray | undefined, template: TemplateLiteral): TaggedTemplateExpression; function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; - function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: ReadonlyArray | undefined, template: TemplateLiteral): TaggedTemplateExpression; + function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: ReadonlyArray | undefined, template: TemplateLiteral): TaggedTemplateExpression; function createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion; function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion; function createParen(expression: Expression): ParenthesizedExpression; @@ -3672,8 +3683,8 @@ declare namespace ts { function createClassExpression(modifiers: ReadonlyArray | undefined, name: string | Identifier | undefined, typeParameters: ReadonlyArray | undefined, heritageClauses: ReadonlyArray | undefined, members: ReadonlyArray): ClassExpression; function updateClassExpression(node: ClassExpression, modifiers: ReadonlyArray | undefined, name: Identifier | undefined, typeParameters: ReadonlyArray | undefined, heritageClauses: ReadonlyArray | undefined, members: ReadonlyArray): ClassExpression; function createOmittedExpression(): OmittedExpression; - function createExpressionWithTypeArguments(typeArguments: ReadonlyArray | undefined, expression: Expression): ExpressionWithTypeArguments; - function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: ReadonlyArray | undefined, expression: Expression): ExpressionWithTypeArguments; + function createExpressionWithTypeArguments(typeArguments: ReadonlyArray | undefined, expression: Expression): ExpressionWithTypeArguments; + function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: ReadonlyArray | undefined, expression: Expression): ExpressionWithTypeArguments; function createAsExpression(expression: Expression, type: TypeNode): AsExpression; function updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression; function createNonNullExpression(expression: Expression): NonNullExpression; @@ -3765,10 +3776,10 @@ declare namespace ts { function updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference; function createJsxElement(openingElement: JsxOpeningElement, children: ReadonlyArray, closingElement: JsxClosingElement): JsxElement; function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: ReadonlyArray, closingElement: JsxClosingElement): JsxElement; - function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxSelfClosingElement; - function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxSelfClosingElement; - function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxOpeningElement; - function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxOpeningElement; + function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxSelfClosingElement; + function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxSelfClosingElement; + function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxOpeningElement; + function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxOpeningElement; function createJsxClosingElement(tagName: JsxTagNameExpression): JsxClosingElement; function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression): JsxClosingElement; function createJsxFragment(openingFragment: JsxOpeningFragment, children: ReadonlyArray, closingFragment: JsxClosingFragment): JsxFragment; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 70f2e0d0cdbf5..3c09eccf3942c 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -221,152 +221,153 @@ declare namespace ts { SetAccessor = 156, CallSignature = 157, ConstructSignature = 158, - IndexSignature = 159, - TypePredicate = 160, - TypeReference = 161, - FunctionType = 162, - ConstructorType = 163, - TypeQuery = 164, - TypeLiteral = 165, - ArrayType = 166, - TupleType = 167, - UnionType = 168, - IntersectionType = 169, - ConditionalType = 170, - InferType = 171, - ParenthesizedType = 172, - ThisType = 173, - TypeOperator = 174, - IndexedAccessType = 175, - MappedType = 176, - LiteralType = 177, - ImportType = 178, - ObjectBindingPattern = 179, - ArrayBindingPattern = 180, - BindingElement = 181, - ArrayLiteralExpression = 182, - ObjectLiteralExpression = 183, - PropertyAccessExpression = 184, - ElementAccessExpression = 185, - CallExpression = 186, - NewExpression = 187, - TaggedTemplateExpression = 188, - TypeAssertionExpression = 189, - ParenthesizedExpression = 190, - FunctionExpression = 191, - ArrowFunction = 192, - DeleteExpression = 193, - TypeOfExpression = 194, - VoidExpression = 195, - AwaitExpression = 196, - PrefixUnaryExpression = 197, - PostfixUnaryExpression = 198, - BinaryExpression = 199, - ConditionalExpression = 200, - TemplateExpression = 201, - YieldExpression = 202, - SpreadElement = 203, - ClassExpression = 204, - OmittedExpression = 205, - ExpressionWithTypeArguments = 206, - AsExpression = 207, - NonNullExpression = 208, - MetaProperty = 209, - TemplateSpan = 210, - SemicolonClassElement = 211, - Block = 212, - VariableStatement = 213, - EmptyStatement = 214, - ExpressionStatement = 215, - IfStatement = 216, - DoStatement = 217, - WhileStatement = 218, - ForStatement = 219, - ForInStatement = 220, - ForOfStatement = 221, - ContinueStatement = 222, - BreakStatement = 223, - ReturnStatement = 224, - WithStatement = 225, - SwitchStatement = 226, - LabeledStatement = 227, - ThrowStatement = 228, - TryStatement = 229, - DebuggerStatement = 230, - VariableDeclaration = 231, - VariableDeclarationList = 232, - FunctionDeclaration = 233, - ClassDeclaration = 234, - InterfaceDeclaration = 235, - TypeAliasDeclaration = 236, - EnumDeclaration = 237, - ModuleDeclaration = 238, - ModuleBlock = 239, - CaseBlock = 240, - NamespaceExportDeclaration = 241, - ImportEqualsDeclaration = 242, - ImportDeclaration = 243, - ImportClause = 244, - NamespaceImport = 245, - NamedImports = 246, - ImportSpecifier = 247, - ExportAssignment = 248, - ExportDeclaration = 249, - NamedExports = 250, - ExportSpecifier = 251, - MissingDeclaration = 252, - ExternalModuleReference = 253, - JsxElement = 254, - JsxSelfClosingElement = 255, - JsxOpeningElement = 256, - JsxClosingElement = 257, - JsxFragment = 258, - JsxOpeningFragment = 259, - JsxClosingFragment = 260, - JsxAttribute = 261, - JsxAttributes = 262, - JsxSpreadAttribute = 263, - JsxExpression = 264, - CaseClause = 265, - DefaultClause = 266, - HeritageClause = 267, - CatchClause = 268, - PropertyAssignment = 269, - ShorthandPropertyAssignment = 270, - SpreadAssignment = 271, - EnumMember = 272, - SourceFile = 273, - Bundle = 274, - UnparsedSource = 275, - InputFiles = 276, - JSDocTypeExpression = 277, - JSDocAllType = 278, - JSDocUnknownType = 279, - JSDocNullableType = 280, - JSDocNonNullableType = 281, - JSDocOptionalType = 282, - JSDocFunctionType = 283, - JSDocVariadicType = 284, - JSDocComment = 285, - JSDocTypeLiteral = 286, - JSDocSignature = 287, - JSDocTag = 288, - JSDocAugmentsTag = 289, - JSDocClassTag = 290, - JSDocCallbackTag = 291, - JSDocParameterTag = 292, - JSDocReturnTag = 293, - JSDocTypeTag = 294, - JSDocTemplateTag = 295, - JSDocTypedefTag = 296, - JSDocPropertyTag = 297, - SyntaxList = 298, - NotEmittedStatement = 299, - PartiallyEmittedExpression = 300, - CommaListExpression = 301, - MergeDeclarationMarker = 302, - EndOfDeclarationMarker = 303, - Count = 304, + NamedTypeArgument = 159, + IndexSignature = 160, + TypePredicate = 161, + TypeReference = 162, + FunctionType = 163, + ConstructorType = 164, + TypeQuery = 165, + TypeLiteral = 166, + ArrayType = 167, + TupleType = 168, + UnionType = 169, + IntersectionType = 170, + ConditionalType = 171, + InferType = 172, + ParenthesizedType = 173, + ThisType = 174, + TypeOperator = 175, + IndexedAccessType = 176, + MappedType = 177, + LiteralType = 178, + ImportType = 179, + ObjectBindingPattern = 180, + ArrayBindingPattern = 181, + BindingElement = 182, + ArrayLiteralExpression = 183, + ObjectLiteralExpression = 184, + PropertyAccessExpression = 185, + ElementAccessExpression = 186, + CallExpression = 187, + NewExpression = 188, + TaggedTemplateExpression = 189, + TypeAssertionExpression = 190, + ParenthesizedExpression = 191, + FunctionExpression = 192, + ArrowFunction = 193, + DeleteExpression = 194, + TypeOfExpression = 195, + VoidExpression = 196, + AwaitExpression = 197, + PrefixUnaryExpression = 198, + PostfixUnaryExpression = 199, + BinaryExpression = 200, + ConditionalExpression = 201, + TemplateExpression = 202, + YieldExpression = 203, + SpreadElement = 204, + ClassExpression = 205, + OmittedExpression = 206, + ExpressionWithTypeArguments = 207, + AsExpression = 208, + NonNullExpression = 209, + MetaProperty = 210, + TemplateSpan = 211, + SemicolonClassElement = 212, + Block = 213, + VariableStatement = 214, + EmptyStatement = 215, + ExpressionStatement = 216, + IfStatement = 217, + DoStatement = 218, + WhileStatement = 219, + ForStatement = 220, + ForInStatement = 221, + ForOfStatement = 222, + ContinueStatement = 223, + BreakStatement = 224, + ReturnStatement = 225, + WithStatement = 226, + SwitchStatement = 227, + LabeledStatement = 228, + ThrowStatement = 229, + TryStatement = 230, + DebuggerStatement = 231, + VariableDeclaration = 232, + VariableDeclarationList = 233, + FunctionDeclaration = 234, + ClassDeclaration = 235, + InterfaceDeclaration = 236, + TypeAliasDeclaration = 237, + EnumDeclaration = 238, + ModuleDeclaration = 239, + ModuleBlock = 240, + CaseBlock = 241, + NamespaceExportDeclaration = 242, + ImportEqualsDeclaration = 243, + ImportDeclaration = 244, + ImportClause = 245, + NamespaceImport = 246, + NamedImports = 247, + ImportSpecifier = 248, + ExportAssignment = 249, + ExportDeclaration = 250, + NamedExports = 251, + ExportSpecifier = 252, + MissingDeclaration = 253, + ExternalModuleReference = 254, + JsxElement = 255, + JsxSelfClosingElement = 256, + JsxOpeningElement = 257, + JsxClosingElement = 258, + JsxFragment = 259, + JsxOpeningFragment = 260, + JsxClosingFragment = 261, + JsxAttribute = 262, + JsxAttributes = 263, + JsxSpreadAttribute = 264, + JsxExpression = 265, + CaseClause = 266, + DefaultClause = 267, + HeritageClause = 268, + CatchClause = 269, + PropertyAssignment = 270, + ShorthandPropertyAssignment = 271, + SpreadAssignment = 272, + EnumMember = 273, + SourceFile = 274, + Bundle = 275, + UnparsedSource = 276, + InputFiles = 277, + JSDocTypeExpression = 278, + JSDocAllType = 279, + JSDocUnknownType = 280, + JSDocNullableType = 281, + JSDocNonNullableType = 282, + JSDocOptionalType = 283, + JSDocFunctionType = 284, + JSDocVariadicType = 285, + JSDocComment = 286, + JSDocTypeLiteral = 287, + JSDocSignature = 288, + JSDocTag = 289, + JSDocAugmentsTag = 290, + JSDocClassTag = 291, + JSDocCallbackTag = 292, + JSDocParameterTag = 293, + JSDocReturnTag = 294, + JSDocTypeTag = 295, + JSDocTemplateTag = 296, + JSDocTypedefTag = 297, + JSDocPropertyTag = 298, + SyntaxList = 299, + NotEmittedStatement = 300, + PartiallyEmittedExpression = 301, + CommaListExpression = 302, + MergeDeclarationMarker = 303, + EndOfDeclarationMarker = 304, + Count = 305, FirstAssignment = 58, LastAssignment = 70, FirstCompoundAssignment = 59, @@ -377,8 +378,8 @@ declare namespace ts { LastKeyword = 144, FirstFutureReservedWord = 108, LastFutureReservedWord = 116, - FirstTypeNode = 160, - LastTypeNode = 178, + FirstTypeNode = 161, + LastTypeNode = 179, FirstPunctuation = 17, LastPunctuation = 70, FirstToken = 0, @@ -392,10 +393,10 @@ declare namespace ts { FirstBinaryOperator = 27, LastBinaryOperator = 70, FirstNode = 145, - FirstJSDocNode = 277, - LastJSDocNode = 297, - FirstJSDocTagNode = 288, - LastJSDocTagNode = 297 + FirstJSDocNode = 278, + LastJSDocNode = 298, + FirstJSDocTagNode = 289, + LastJSDocTagNode = 298 } enum NodeFlags { None = 0, @@ -701,6 +702,12 @@ declare namespace ts { interface TypeNode extends Node { _typeNodeBrand: any; } + interface NamedTypeArgument extends Node { + kind: SyntaxKind.NamedTypeArgument; + name: Identifier; + type: TypeNode; + } + type TypeArgument = TypeNode | NamedTypeArgument; interface KeywordTypeNode extends TypeNode { kind: SyntaxKind.AnyKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.VoidKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.NullKeyword | SyntaxKind.NeverKeyword; } @@ -721,7 +728,7 @@ declare namespace ts { kind: SyntaxKind.ConstructorType; } interface NodeWithTypeArguments extends TypeNode { - typeArguments?: NodeArray; + typeArguments?: NodeArray; } type TypeReferenceType = TypeReferenceNode | ExpressionWithTypeArguments; interface TypeReferenceNode extends NodeWithTypeArguments { @@ -1033,7 +1040,7 @@ declare namespace ts { interface CallExpression extends LeftHandSideExpression, Declaration { kind: SyntaxKind.CallExpression; expression: LeftHandSideExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; arguments: NodeArray; } interface SuperCall extends CallExpression { @@ -1050,13 +1057,13 @@ declare namespace ts { interface NewExpression extends PrimaryExpression, Declaration { kind: SyntaxKind.NewExpression; expression: LeftHandSideExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; arguments?: NodeArray; } interface TaggedTemplateExpression extends MemberExpression { kind: SyntaxKind.TaggedTemplateExpression; tag: LeftHandSideExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; template: TemplateLiteral; } type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement; @@ -1096,13 +1103,13 @@ declare namespace ts { kind: SyntaxKind.JsxOpeningElement; parent: JsxElement; tagName: JsxTagNameExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; attributes: JsxAttributes; } interface JsxSelfClosingElement extends PrimaryExpression { kind: SyntaxKind.JsxSelfClosingElement; tagName: JsxTagNameExpression; - typeArguments?: NodeArray; + typeArguments?: NodeArray; attributes: JsxAttributes; } interface JsxFragment extends PrimaryExpression { @@ -1814,7 +1821,7 @@ declare namespace ts { typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode | undefined; /** Note that the resulting nodes cannot be checked. */ signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): (SignatureDeclaration & { - typeArguments?: NodeArray; + typeArguments?: NodeArray; }) | undefined; /** Note that the resulting nodes cannot be checked. */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): IndexSignatureDeclaration | undefined; @@ -3250,6 +3257,7 @@ declare namespace ts { function isSetAccessorDeclaration(node: Node): node is SetAccessorDeclaration; function isCallSignatureDeclaration(node: Node): node is CallSignatureDeclaration; function isConstructSignatureDeclaration(node: Node): node is ConstructSignatureDeclaration; + function isNamedTypeArgument(node: Node): node is NamedTypeArgument; function isIndexSignatureDeclaration(node: Node): node is IndexSignatureDeclaration; function isTypePredicateNode(node: Node): node is TypePredicateNode; function isTypeReferenceNode(node: Node): node is TypeReferenceNode; @@ -3418,6 +3426,7 @@ declare namespace ts { * of a TypeNode. */ function isTypeNode(node: Node): node is TypeNode; + function isTypeArgument(node: Node): node is TypeArgument; function isFunctionOrConstructorTypeNode(node: Node): node is FunctionTypeNode | ConstructorTypeNode; function isPropertyAccessOrQualifiedName(node: Node): node is PropertyAccessExpression | QualifiedName; function isCallLikeExpression(node: Node): node is CallLikeExpression; @@ -3567,13 +3576,15 @@ declare namespace ts { function updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): CallSignatureDeclaration; function createConstructSignature(typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined): ConstructSignatureDeclaration; function updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): ConstructSignatureDeclaration; + function createNamedTypeArgument(name: string | Identifier, type: TypeNode): NamedTypeArgument; + function updateNamedTypeArgument(node: NamedTypeArgument, name: Identifier, type: TypeNode): NamedTypeArgument; function createIndexSignature(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode): IndexSignatureDeclaration; function updateIndexSignature(node: IndexSignatureDeclaration, decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode): IndexSignatureDeclaration; function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode; function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode): TypePredicateNode; function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode): TypePredicateNode; - function createTypeReferenceNode(typeName: string | EntityName, typeArguments: ReadonlyArray | undefined): TypeReferenceNode; - function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; + function createTypeReferenceNode(typeName: string | EntityName, typeArguments: ReadonlyArray | undefined): TypeReferenceNode; + function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; function createFunctionTypeNode(typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined): FunctionTypeNode; function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): FunctionTypeNode; function createConstructorTypeNode(typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined): ConstructorTypeNode; @@ -3595,8 +3606,8 @@ declare namespace ts { function updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; function createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode; function updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode; - function createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: ReadonlyArray, isTypeOf?: boolean): ImportTypeNode; - function updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier?: EntityName, typeArguments?: ReadonlyArray, isTypeOf?: boolean): ImportTypeNode; + function createImportTypeNode(argument: TypeNode, qualifier?: EntityName, typeArguments?: ReadonlyArray, isTypeOf?: boolean): ImportTypeNode; + function updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier?: EntityName, typeArguments?: ReadonlyArray, isTypeOf?: boolean): ImportTypeNode; function createParenthesizedType(type: TypeNode): ParenthesizedTypeNode; function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode; function createThisTypeNode(): ThisTypeNode; @@ -3623,14 +3634,14 @@ declare namespace ts { function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression; function createElementAccess(expression: Expression, index: number | Expression): ElementAccessExpression; function updateElementAccess(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression; - function createCall(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): CallExpression; - function updateCall(node: CallExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray): CallExpression; - function createNew(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; - function updateNew(node: NewExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; + function createCall(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): CallExpression; + function updateCall(node: CallExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray): CallExpression; + function createNew(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; + function updateNew(node: NewExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; - function createTaggedTemplate(tag: Expression, typeArguments: ReadonlyArray | undefined, template: TemplateLiteral): TaggedTemplateExpression; + function createTaggedTemplate(tag: Expression, typeArguments: ReadonlyArray | undefined, template: TemplateLiteral): TaggedTemplateExpression; function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; - function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: ReadonlyArray | undefined, template: TemplateLiteral): TaggedTemplateExpression; + function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: ReadonlyArray | undefined, template: TemplateLiteral): TaggedTemplateExpression; function createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion; function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion; function createParen(expression: Expression): ParenthesizedExpression; @@ -3672,8 +3683,8 @@ declare namespace ts { function createClassExpression(modifiers: ReadonlyArray | undefined, name: string | Identifier | undefined, typeParameters: ReadonlyArray | undefined, heritageClauses: ReadonlyArray | undefined, members: ReadonlyArray): ClassExpression; function updateClassExpression(node: ClassExpression, modifiers: ReadonlyArray | undefined, name: Identifier | undefined, typeParameters: ReadonlyArray | undefined, heritageClauses: ReadonlyArray | undefined, members: ReadonlyArray): ClassExpression; function createOmittedExpression(): OmittedExpression; - function createExpressionWithTypeArguments(typeArguments: ReadonlyArray | undefined, expression: Expression): ExpressionWithTypeArguments; - function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: ReadonlyArray | undefined, expression: Expression): ExpressionWithTypeArguments; + function createExpressionWithTypeArguments(typeArguments: ReadonlyArray | undefined, expression: Expression): ExpressionWithTypeArguments; + function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: ReadonlyArray | undefined, expression: Expression): ExpressionWithTypeArguments; function createAsExpression(expression: Expression, type: TypeNode): AsExpression; function updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression; function createNonNullExpression(expression: Expression): NonNullExpression; @@ -3765,10 +3776,10 @@ declare namespace ts { function updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference; function createJsxElement(openingElement: JsxOpeningElement, children: ReadonlyArray, closingElement: JsxClosingElement): JsxElement; function updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: ReadonlyArray, closingElement: JsxClosingElement): JsxElement; - function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxSelfClosingElement; - function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxSelfClosingElement; - function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxOpeningElement; - function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxOpeningElement; + function createJsxSelfClosingElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxSelfClosingElement; + function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxSelfClosingElement; + function createJsxOpeningElement(tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxOpeningElement; + function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, typeArguments: ReadonlyArray | undefined, attributes: JsxAttributes): JsxOpeningElement; function createJsxClosingElement(tagName: JsxTagNameExpression): JsxClosingElement; function updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNameExpression): JsxClosingElement; function createJsxFragment(openingFragment: JsxOpeningFragment, children: ReadonlyArray, closingFragment: JsxClosingFragment): JsxFragment; diff --git a/tests/baselines/reference/jsxChildrenGenericContextualTypes.errors.txt b/tests/baselines/reference/jsxChildrenGenericContextualTypes.errors.txt index 632264144dd36..02947d7711718 100644 --- a/tests/baselines/reference/jsxChildrenGenericContextualTypes.errors.txt +++ b/tests/baselines/reference/jsxChildrenGenericContextualTypes.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(20,31): error TS2326: Types of property 'children' are incompatible. - Type '(p: IntrinsicAttributes & LitProps<"x">) => "y"' is not assignable to type '(x: IntrinsicAttributes & LitProps<"x">) => "x"'. + Type '(p: LitProps<"x">) => "y"' is not assignable to type '(x: IntrinsicAttributes & LitProps<"x">) => "x"'. Type '"y"' is not assignable to type '"x"'. tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(21,19): error TS2322: Type '{ children: (p: IntrinsicAttributes & LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'IntrinsicAttributes & LitProps<"x" | "y">'. Type '{ children: (p: IntrinsicAttributes & LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'LitProps<"x" | "y">'. @@ -41,7 +41,7 @@ tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(22,21): error TS2322: const arg = "y"} /> ~~~~~~~~~~~~~~~~~~~ !!! error TS2326: Types of property 'children' are incompatible. -!!! error TS2326: Type '(p: IntrinsicAttributes & LitProps<"x">) => "y"' is not assignable to type '(x: IntrinsicAttributes & LitProps<"x">) => "x"'. +!!! error TS2326: Type '(p: LitProps<"x">) => "y"' is not assignable to type '(x: IntrinsicAttributes & LitProps<"x">) => "x"'. !!! error TS2326: Type '"y"' is not assignable to type '"x"'. const argchild = {p => "y"} ~~~~~~~ diff --git a/tests/baselines/reference/jsxChildrenGenericContextualTypes.types b/tests/baselines/reference/jsxChildrenGenericContextualTypes.types index 0196248d39c10..5063cad2555a8 100644 --- a/tests/baselines/reference/jsxChildrenGenericContextualTypes.types +++ b/tests/baselines/reference/jsxChildrenGenericContextualTypes.types @@ -139,9 +139,9 @@ const arg = "y"} /> > "y"} /> : JSX.Element >ElemLit : (p: LitProps) => JSX.Element >prop : "x" ->children : (p: JSX.IntrinsicAttributes & LitProps<"x">) => "y" ->p => "y" : (p: JSX.IntrinsicAttributes & LitProps<"x">) => "y" ->p : JSX.IntrinsicAttributes & LitProps<"x"> +>children : (p: LitProps<"x">) => "y" +>p => "y" : (p: LitProps<"x">) => "y" +>p : LitProps<"x"> >"y" : "y" const argchild = {p => "y"} diff --git a/tests/baselines/reference/typeArgumentListWithNamedTypeArgumentsAndDefaults.js b/tests/baselines/reference/typeArgumentListWithNamedTypeArgumentsAndDefaults.js new file mode 100644 index 0000000000000..d6dcd063d8f4c --- /dev/null +++ b/tests/baselines/reference/typeArgumentListWithNamedTypeArgumentsAndDefaults.js @@ -0,0 +1,23 @@ +//// [typeArgumentListWithNamedTypeArgumentsAndDefaults.ts] +class Foo { + constructor(public a?: A, public b?: B) {} +} + +const x = new Foo(); +x.a.x; +x.a.y; +x.b; + + +//// [typeArgumentListWithNamedTypeArgumentsAndDefaults.js] +var Foo = /** @class */ (function () { + function Foo(a, b) { + this.a = a; + this.b = b; + } + return Foo; +}()); +var x = new Foo(); +x.a.x; +x.a.y; +x.b; diff --git a/tests/baselines/reference/typeArgumentListWithNamedTypeArgumentsAndDefaults.symbols b/tests/baselines/reference/typeArgumentListWithNamedTypeArgumentsAndDefaults.symbols new file mode 100644 index 0000000000000..a76f82e63a22a --- /dev/null +++ b/tests/baselines/reference/typeArgumentListWithNamedTypeArgumentsAndDefaults.symbols @@ -0,0 +1,39 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListWithNamedTypeArgumentsAndDefaults.ts === +class Foo { +>Foo : Symbol(Foo, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 0, 0)) +>A : Symbol(A, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 0, 10)) +>x : Symbol(x, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 0, 21)) +>x : Symbol(x, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 0, 35)) +>y : Symbol(y, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 0, 45)) +>B : Symbol(B, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 0, 57)) + + constructor(public a?: A, public b?: B) {} +>a : Symbol(Foo.a, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 1, 16)) +>A : Symbol(A, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 0, 10)) +>b : Symbol(Foo.b, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 1, 29)) +>B : Symbol(B, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 0, 57)) +} + +const x = new Foo(); +>x : Symbol(x, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 4, 5)) +>Foo : Symbol(Foo, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 0, 0)) + +x.a.x; +>x.a.x : Symbol(x, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 0, 35)) +>x.a : Symbol(Foo.a, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 1, 16)) +>x : Symbol(x, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 4, 5)) +>a : Symbol(Foo.a, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 1, 16)) +>x : Symbol(x, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 0, 35)) + +x.a.y; +>x.a.y : Symbol(y, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 0, 45)) +>x.a : Symbol(Foo.a, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 1, 16)) +>x : Symbol(x, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 4, 5)) +>a : Symbol(Foo.a, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 1, 16)) +>y : Symbol(y, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 0, 45)) + +x.b; +>x.b : Symbol(Foo.b, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 1, 29)) +>x : Symbol(x, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 4, 5)) +>b : Symbol(Foo.b, Decl(typeArgumentListWithNamedTypeArgumentsAndDefaults.ts, 1, 29)) + diff --git a/tests/baselines/reference/typeArgumentListWithNamedTypeArgumentsAndDefaults.types b/tests/baselines/reference/typeArgumentListWithNamedTypeArgumentsAndDefaults.types new file mode 100644 index 0000000000000..b87bb816a5402 --- /dev/null +++ b/tests/baselines/reference/typeArgumentListWithNamedTypeArgumentsAndDefaults.types @@ -0,0 +1,41 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListWithNamedTypeArgumentsAndDefaults.ts === +class Foo { +>Foo : Foo +>A : A +>x : string +>x : string +>y : number +>B : B + + constructor(public a?: A, public b?: B) {} +>a : A +>A : A +>b : B +>B : B +} + +const x = new Foo(); +>x : Foo<{ x: string; y: number; }, string> +>new Foo() : Foo<{ x: string; y: number; }, string> +>Foo : typeof Foo +>B : any + +x.a.x; +>x.a.x : string +>x.a : { x: string; y: number; } +>x : Foo<{ 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 : Foo<{ x: string; y: number; }, string> +>a : { x: string; y: number; } +>y : number + +x.b; +>x.b : string +>x : Foo<{ x: string; y: number; }, string> +>b : string + diff --git a/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentErrors.errors.txt b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentErrors.errors.txt new file mode 100644 index 0000000000000..5e3e79ad32dd2 --- /dev/null +++ b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentErrors.errors.txt @@ -0,0 +1,202 @@ +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(28,35): error TS1347: Signature has no type argument named 'Q'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(29,29): error TS1347: Signature has no type argument named 'Q'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(30,29): error TS1347: Signature has no type argument named 'Q'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(31,33): error TS1347: Signature has no type argument named 'Q'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(32,14): error TS1351: No value provided for required type argument 'U'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(32,22): error TS1347: Signature has no type argument named 'Q'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(36,27): error TS1346: Positional type argument conflicts with named type argument 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(36,35): error TS1345: Named type argument conflicts with positional type argument at index '0'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(37,21): error TS1346: Positional type argument conflicts with named type argument 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(37,29): error TS1345: Named type argument conflicts with positional type argument at index '0'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(38,21): error TS1346: Positional type argument conflicts with named type argument 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(38,29): error TS1345: Named type argument conflicts with positional type argument at index '0'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(39,25): error TS1346: Positional type argument conflicts with named type argument 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(39,33): error TS1345: Named type argument conflicts with positional type argument at index '0'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(40,14): error TS1346: Positional type argument conflicts with named type argument 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(40,14): error TS1351: No value provided for required type argument 'U'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(40,22): error TS1345: Named type argument conflicts with positional type argument at index '0'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(44,27): error TS2300: Duplicate identifier 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(44,39): error TS2300: Duplicate identifier 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(44,51): error TS2345: Argument of type '0' is not assignable to parameter of type 'string'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(45,21): error TS2300: Duplicate identifier 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(45,33): error TS2300: Duplicate identifier 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(45,45): error TS2345: Argument of type '0' is not assignable to parameter of type 'string'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(46,21): error TS2300: Duplicate identifier 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(46,33): error TS2300: Duplicate identifier 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(47,25): error TS2300: Duplicate identifier 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(47,37): error TS2300: Duplicate identifier 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(47,49): error TS2326: Types of property 'x' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(47,88): error TS2339: Property 'toFixed' does not exist on type 'string'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(48,14): error TS2300: Duplicate identifier 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(48,14): error TS1351: No value provided for required type argument 'U'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(48,26): error TS2300: Duplicate identifier 'T'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(52,27): error TS2558: Expected 0-2 type arguments, but got 3. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(53,21): error TS2558: Expected 0-2 type arguments, but got 3. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(54,21): error TS2558: Expected 0-2 type arguments, but got 3. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(55,25): error TS2558: Expected 0-2 type arguments, but got 3. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(56,10): error TS2314: Generic type 'Foo' requires 2 type argument(s). +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(60,39): error TS1344: Positional type arguments cannot follow named type arguments. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(61,33): error TS1344: Positional type arguments cannot follow named type arguments. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(62,33): error TS1344: Positional type arguments cannot follow named type arguments. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(63,37): error TS1344: Positional type arguments cannot follow named type arguments. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(64,26): error TS1344: Positional type arguments cannot follow named type arguments. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx(67,10): error TS2314: Generic type 'Foo' requires 2 type argument(s). + + +==== tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx (43 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 ; + } + + // Does not reference valid param + + const instance1 = new Foo(0, ""); + ~ +!!! error TS1347: Signature has no type argument named 'Q'. + const result1 = foo(0, ""); + ~ +!!! error TS1347: Signature has no type argument named 'Q'. + const tagged1 = tag`tags ${12} ${""}`; + ~ +!!! error TS1347: Signature has no type argument named 'Q'. + const jsx1 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + ~ +!!! error TS1347: Signature has no type argument named 'Q'. + type A = Foo; + ~~~~~~~~~~~~~~~~~~ +!!! error TS1351: No value provided for required type argument 'U'. + ~ +!!! error TS1347: Signature has no type argument named 'Q'. + + // Duplicates positional + + const instance2 = new Foo(0, ""); + ~~~~~~ +!!! error TS1346: Positional type argument conflicts with named type argument 'T'. + ~ +!!! error TS1345: Named type argument conflicts with positional type argument at index '0'. + const result2 = foo(0, ""); + ~~~~~~ +!!! error TS1346: Positional type argument conflicts with named type argument 'T'. + ~ +!!! error TS1345: Named type argument conflicts with positional type argument at index '0'. + const tagged2 = tag`tags ${12} ${""}`; + ~~~~~~ +!!! error TS1346: Positional type argument conflicts with named type argument 'T'. + ~ +!!! error TS1345: Named type argument conflicts with positional type argument at index '0'. + const jsx2 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + ~~~~~~ +!!! error TS1346: Positional type argument conflicts with named type argument 'T'. + ~ +!!! error TS1345: Named type argument conflicts with positional type argument at index '0'. + type B = Foo; + ~~~~~~ +!!! error TS1346: Positional type argument conflicts with named type argument 'T'. + ~~~~~~~~~~~~~~~~~~ +!!! error TS1351: No value provided for required type argument 'U'. + ~ +!!! error TS1345: Named type argument conflicts with positional type argument at index '0'. + + // Duplicates other named + + const instance3 = new Foo(0, ""); + ~ +!!! error TS2300: Duplicate identifier 'T'. + ~ +!!! error TS2300: Duplicate identifier 'T'. + ~ +!!! error TS2345: Argument of type '0' is not assignable to parameter of type 'string'. + const result3 = foo(0, ""); + ~ +!!! error TS2300: Duplicate identifier 'T'. + ~ +!!! error TS2300: Duplicate identifier 'T'. + ~ +!!! error TS2345: Argument of type '0' is not assignable to parameter of type 'string'. + const tagged3 = tag`tags ${12} ${""}`; + ~ +!!! error TS2300: Duplicate identifier 'T'. + ~ +!!! error TS2300: Duplicate identifier 'T'. + const jsx3 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + ~ +!!! error TS2300: Duplicate identifier 'T'. + ~ +!!! error TS2300: Duplicate identifier 'T'. + ~~~~~~ +!!! error TS2326: Types of property 'x' are incompatible. +!!! error TS2326: Type 'number' is not assignable to type 'string'. + ~~~~~~~ +!!! error TS2339: Property 'toFixed' does not exist on type 'string'. + type C = Foo; + ~ +!!! error TS2300: Duplicate identifier 'T'. + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1351: No value provided for required type argument 'U'. + ~ +!!! error TS2300: Duplicate identifier 'T'. + + // Too many arguments + + const instance4 = new Foo(0, ""); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2558: Expected 0-2 type arguments, but got 3. + const result4 = foo(0, ""); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2558: Expected 0-2 type arguments, but got 3. + const tagged4 = tag`tags ${12} ${""}`; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2558: Expected 0-2 type arguments, but got 3. + const jsx4 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2558: Expected 0-2 type arguments, but got 3. + type D = Foo; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2314: Generic type 'Foo' requires 2 type argument(s). + + // Positional after named + + const instance5 = new Foo(0, ""); + ~~~~~~ +!!! error TS1344: Positional type arguments cannot follow named type arguments. + const result5 = foo(0, ""); + ~~~~~~ +!!! error TS1344: Positional type arguments cannot follow named type arguments. + const tagged5 = tag`tags ${12} ${""}`; + ~~~~~~ +!!! error TS1344: Positional type arguments cannot follow named type arguments. + const jsx5 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + ~~~~~~ +!!! error TS1344: Positional type arguments cannot follow named type arguments. + type E = Foo; + ~~~~~~ +!!! error TS1344: Positional type arguments cannot follow named type arguments. + + // Typespace only - does not provide enough arguments + type F = Foo; + ~~~~~~~~~~~~~~~ +!!! error TS2314: Generic type 'Foo' requires 2 type argument(s). + \ No newline at end of file diff --git a/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentErrors.js b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentErrors.js new file mode 100644 index 0000000000000..9195ef2d354bc --- /dev/null +++ b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentErrors.js @@ -0,0 +1,118 @@ +//// [typeArgumentListsWithNamedTypeArgumentErrors.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 ; +} + +// Does not reference valid param + +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())} />; +type A = Foo; + +// Duplicates positional + +const instance2 = new Foo(0, ""); +const result2 = foo(0, ""); +const tagged2 = tag`tags ${12} ${""}`; +const jsx2 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +type B = Foo; + +// Duplicates other named + +const instance3 = new Foo(0, ""); +const result3 = foo(0, ""); +const tagged3 = tag`tags ${12} ${""}`; +const jsx3 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +type C = Foo; + +// Too many arguments + +const instance4 = new Foo(0, ""); +const result4 = foo(0, ""); +const tagged4 = tag`tags ${12} ${""}`; +const jsx4 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +type D = Foo; + +// Positional after named + +const instance5 = new Foo(0, ""); +const result5 = foo(0, ""); +const tagged5 = tag`tags ${12} ${""}`; +const jsx5 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +type E = Foo; + +// Typespace only - does not provide enough arguments +type F = Foo; + + +//// [typeArgumentListsWithNamedTypeArgumentErrors.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); +} +// Does not reference valid param +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()); } }); +// Duplicates positional +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()); } }); +// Duplicates other named +var instance3 = new Foo(0, ""); +var result3 = foo(0, ""); +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()); } }); +// Too many arguments +var instance4 = new Foo(0, ""); +var result4 = foo(0, ""); +var tagged4 = tag(__makeTemplateObject(["tags ", " ", ""], ["tags ", " ", ""]), 12, ""); +var jsx4 = React.createElement(Component, { x: 12, y: "", cb: function (props) { return void (props.x.toFixed() + props.y.toUpperCase()); } }); +// Positional after named +var instance5 = new Foo(0, ""); +var result5 = foo(0, ""); +var tagged5 = tag(__makeTemplateObject(["tags ", " ", ""], ["tags ", " ", ""]), 12, ""); +var jsx5 = React.createElement(Component, { x: 12, y: "", cb: function (props) { return void (props.x.toFixed() + props.y.toUpperCase()); } }); diff --git a/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentErrors.symbols b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentErrors.symbols new file mode 100644 index 0000000000000..5aa2d58fa73e8 --- /dev/null +++ b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentErrors.symbols @@ -0,0 +1,268 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 0, 0)) + + interface Element {} +>Element : Symbol(Element, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 0, 20)) +} +declare namespace React { +>React : Symbol(React, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 2, 1)) + + export function createElement(x: any, p: any, ...children: any[]): JSX.Element; +>createElement : Symbol(createElement, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 3, 25)) +>x : Symbol(x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 4, 34)) +>p : Symbol(p, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 4, 41)) +>children : Symbol(children, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 4, 49)) +>JSX : Symbol(JSX, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 0, 0)) +>Element : Symbol(JSX.Element, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 0, 20)) +} + +class Foo { +>Foo : Symbol(Foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 5, 1)) +>T : Symbol(T, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 7, 10)) +>U : Symbol(U, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 7, 12)) + + constructor(public prop1: T, public prop2: U) {} +>prop1 : Symbol(Foo.prop1, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 8, 16)) +>T : Symbol(T, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 7, 10)) +>prop2 : Symbol(Foo.prop2, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 8, 32)) +>U : Symbol(U, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 7, 12)) +} + +function foo(x: T, y: U): [T, U] { return [x, y]; } +>foo : Symbol(foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 9, 1)) +>T : Symbol(T, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 13)) +>U : Symbol(U, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 15)) +>x : Symbol(x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 19)) +>T : Symbol(T, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 13)) +>y : Symbol(y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 24)) +>U : Symbol(U, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 15)) +>T : Symbol(T, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 13)) +>U : Symbol(U, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 15)) +>x : Symbol(x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 19)) +>y : Symbol(y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 24)) + +function tag(x: TemplateStringsArray, ...args: (T | U)[]) { return args; } +>tag : Symbol(tag, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 57)) +>T : Symbol(T, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 13, 13)) +>U : Symbol(U, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 13, 15)) +>x : Symbol(x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 13, 19)) +>TemplateStringsArray : Symbol(TemplateStringsArray, Decl(lib.d.ts, --, --)) +>args : Symbol(args, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 13, 43)) +>T : Symbol(T, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 13, 13)) +>U : Symbol(U, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 13, 15)) +>args : Symbol(args, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 13, 43)) + +interface ComponentProps { +>ComponentProps : Symbol(ComponentProps, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 13, 80)) +>T : Symbol(T, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 25)) +>U : Symbol(U, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 27)) + + x: T; +>x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 32)) +>T : Symbol(T, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 25)) + + y: U; +>y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 16, 9)) +>U : Symbol(U, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 27)) + + cb(props: this): void; +>cb : Symbol(ComponentProps.cb, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 17, 9)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 18, 7)) +} + +function Component(x: ComponentProps) { +>Component : Symbol(Component, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 19, 1)) +>T : Symbol(T, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 21, 19)) +>U : Symbol(U, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 21, 21)) +>x : Symbol(x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 21, 25)) +>ComponentProps : Symbol(ComponentProps, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 13, 80)) +>T : Symbol(T, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 21, 19)) +>U : Symbol(U, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 21, 21)) + + return ; +} + +// Does not reference valid param + +const instance1 = new Foo(0, ""); +>instance1 : Symbol(instance1, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 27, 5)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 5, 1)) + +const result1 = foo(0, ""); +>result1 : Symbol(result1, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 28, 5)) +>foo : Symbol(foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 9, 1)) + +const tagged1 = tag`tags ${12} ${""}`; +>tagged1 : Symbol(tagged1, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 29, 5)) +>tag : Symbol(tag, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 57)) + +const jsx1 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx1 : Symbol(jsx1, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 30, 5)) +>Component : Symbol(Component, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 19, 1)) +>x : Symbol(x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 30, 43)) +>y : Symbol(y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 30, 50)) +>cb : Symbol(cb, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 30, 55)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 30, 60)) +>props.x.toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 32)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 30, 60)) +>x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 32)) +>toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.y.toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) +>props.y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 16, 9)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 30, 60)) +>y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 16, 9)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) + +type A = Foo; +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 30, 122)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 5, 1)) + +// Duplicates positional + +const instance2 = new Foo(0, ""); +>instance2 : Symbol(instance2, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 35, 5)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 5, 1)) + +const result2 = foo(0, ""); +>result2 : Symbol(result2, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 36, 5)) +>foo : Symbol(foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 9, 1)) + +const tagged2 = tag`tags ${12} ${""}`; +>tagged2 : Symbol(tagged2, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 37, 5)) +>tag : Symbol(tag, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 57)) + +const jsx2 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx2 : Symbol(jsx2, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 38, 5)) +>Component : Symbol(Component, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 19, 1)) +>x : Symbol(x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 38, 43)) +>y : Symbol(y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 38, 50)) +>cb : Symbol(cb, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 38, 55)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 38, 60)) +>props.x.toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 32)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 38, 60)) +>x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 32)) +>toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.y.toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) +>props.y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 16, 9)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 38, 60)) +>y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 16, 9)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) + +type B = Foo; +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 38, 122)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 5, 1)) + +// Duplicates other named + +const instance3 = new Foo(0, ""); +>instance3 : Symbol(instance3, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 43, 5)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 5, 1)) + +const result3 = foo(0, ""); +>result3 : Symbol(result3, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 44, 5)) +>foo : Symbol(foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 9, 1)) + +const tagged3 = tag`tags ${12} ${""}`; +>tagged3 : Symbol(tagged3, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 45, 5)) +>tag : Symbol(tag, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 57)) + +const jsx3 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx3 : Symbol(jsx3, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 46, 5)) +>Component : Symbol(Component, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 19, 1)) +>x : Symbol(x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 46, 47)) +>y : Symbol(y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 46, 54)) +>cb : Symbol(cb, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 46, 59)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 46, 64)) +>props.x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 32)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 46, 64)) +>x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 32)) +>props.y.toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) +>props.y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 16, 9)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 46, 64)) +>y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 16, 9)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) + +type C = Foo; +>C : Symbol(C, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 46, 126)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 5, 1)) + +// Too many arguments + +const instance4 = new Foo(0, ""); +>instance4 : Symbol(instance4, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 51, 5)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 5, 1)) + +const result4 = foo(0, ""); +>result4 : Symbol(result4, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 52, 5)) +>foo : Symbol(foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 9, 1)) + +const tagged4 = tag`tags ${12} ${""}`; +>tagged4 : Symbol(tagged4, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 53, 5)) +>tag : Symbol(tag, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 57)) + +const jsx4 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx4 : Symbol(jsx4, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 54, 5)) +>Component : Symbol(Component, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 19, 1)) +>x : Symbol(x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 54, 58)) +>y : Symbol(y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 54, 65)) +>cb : Symbol(cb, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 54, 70)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 54, 75)) +>props.x.toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 32)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 54, 75)) +>x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 32)) +>toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.y.toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) +>props.y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 16, 9)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 54, 75)) +>y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 16, 9)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) + +type D = Foo; +>D : Symbol(D, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 54, 137)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 5, 1)) + +// Positional after named + +const instance5 = new Foo(0, ""); +>instance5 : Symbol(instance5, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 59, 5)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 5, 1)) + +const result5 = foo(0, ""); +>result5 : Symbol(result5, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 60, 5)) +>foo : Symbol(foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 9, 1)) + +const tagged5 = tag`tags ${12} ${""}`; +>tagged5 : Symbol(tagged5, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 61, 5)) +>tag : Symbol(tag, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 11, 57)) + +const jsx5 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx5 : Symbol(jsx5, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 62, 5)) +>Component : Symbol(Component, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 19, 1)) +>x : Symbol(x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 62, 43)) +>y : Symbol(y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 62, 50)) +>cb : Symbol(cb, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 62, 55)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 62, 60)) +>props.x.toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 32)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 62, 60)) +>x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 15, 32)) +>toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.y.toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) +>props.y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 16, 9)) +>props : Symbol(props, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 62, 60)) +>y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 16, 9)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) + +type E = Foo; +>E : Symbol(E, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 62, 122)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 5, 1)) + +// Typespace only - does not provide enough arguments +type F = Foo; +>F : Symbol(F, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 63, 33)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithNamedTypeArgumentErrors.tsx, 5, 1)) + diff --git a/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentErrors.types b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentErrors.types new file mode 100644 index 0000000000000..9174ac83e9343 --- /dev/null +++ b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentErrors.types @@ -0,0 +1,405 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx === +declare module JSX { +>JSX : any + + interface Element {} +>Element : 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 +>Element : JSX.Element +} + +class Foo { +>Foo : Foo +>T : T +>U : U + + constructor(public prop1: T, public prop2: U) {} +>prop1 : T +>T : T +>prop2 : U +>U : U +} + +function foo(x: T, y: U): [T, U] { return [x, y]; } +>foo : (x: T, y: U) => [T, U] +>T : T +>U : U +>x : T +>T : T +>y : U +>U : U +>T : T +>U : 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)[] +>T : T +>U : U +>x : TemplateStringsArray +>TemplateStringsArray : TemplateStringsArray +>args : (T | U)[] +>T : T +>U : U +>args : (T | U)[] + +interface ComponentProps { +>ComponentProps : ComponentProps +>T : T +>U : U + + x: T; +>x : T +>T : T + + y: U; +>y : U +>U : U + + cb(props: this): void; +>cb : (props: this) => void +>props : this +} + +function Component(x: ComponentProps) { +>Component : (x: ComponentProps) => JSX.Element +>T : T +>U : U +>x : ComponentProps +>ComponentProps : ComponentProps +>T : T +>U : U + + return ; +> : JSX.Element +>h : any +>h : any +} + +// Does not reference valid param + +const instance1 = new Foo(0, ""); +>instance1 : any +>new Foo(0, "") : any +>Foo : typeof Foo +>Q : any +>0 : 0 +>"" : "" + +const result1 = foo(0, ""); +>result1 : any +>foo(0, "") : any +>foo : (x: T, y: U) => [T, U] +>Q : any +>0 : 0 +>"" : "" + +const tagged1 = tag`tags ${12} ${""}`; +>tagged1 : any +>tag`tags ${12} ${""}` : any +>tag : (x: TemplateStringsArray, ...args: (T | U)[]) => (T | U)[] +>Q : any +>`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 +>Q : any +>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 + +type A = Foo; +>A : Foo +>Foo : Foo +>Q : any + +// Duplicates positional + +const instance2 = new Foo(0, ""); +>instance2 : any +>new Foo(0, "") : any +>Foo : typeof Foo +>T : any +>0 : 0 +>"" : "" + +const result2 = foo(0, ""); +>result2 : any +>foo(0, "") : any +>foo : (x: T, y: U) => [T, U] +>T : any +>0 : 0 +>"" : "" + +const tagged2 = tag`tags ${12} ${""}`; +>tagged2 : any +>tag`tags ${12} ${""}` : any +>tag : (x: TemplateStringsArray, ...args: (T | U)[]) => (T | U)[] +>T : any +>`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 +>T : any +>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 + +type B = Foo; +>B : Foo +>Foo : Foo +>T : any + +// Duplicates other named + +const instance3 = new Foo(0, ""); +>instance3 : any +>new Foo(0, "") : any +>Foo : typeof Foo +>T : any +>T : any +>0 : 0 +>"" : "" + +const result3 = foo(0, ""); +>result3 : any +>foo(0, "") : any +>foo : (x: T, y: U) => [T, U] +>T : any +>T : any +>0 : 0 +>"" : "" + +const tagged3 = tag`tags ${12} ${""}`; +>tagged3 : (string | number)[] +>tag`tags ${12} ${""}` : (string | number)[] +>tag : (x: TemplateStringsArray, ...args: (T | U)[]) => (T | U)[] +>T : any +>T : any +>`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 +>T : any +>T : any +>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() : any +>props.x.toFixed : any +>props.x : string +>props : ComponentProps +>x : string +>toFixed : any +>props.y.toUpperCase() : string +>props.y.toUpperCase : () => string +>props.y : string +>props : ComponentProps +>y : string +>toUpperCase : () => string + +type C = Foo; +>C : Foo +>Foo : Foo +>T : any +>T : any + +// Too many arguments + +const instance4 = new Foo(0, ""); +>instance4 : any +>new Foo(0, "") : any +>Foo : typeof Foo +>T : any +>U : any +>W : any +>0 : 0 +>"" : "" + +const result4 = foo(0, ""); +>result4 : any +>foo(0, "") : any +>foo : (x: T, y: U) => [T, U] +>T : any +>U : any +>W : any +>0 : 0 +>"" : "" + +const tagged4 = tag`tags ${12} ${""}`; +>tagged4 : any +>tag`tags ${12} ${""}` : any +>tag : (x: TemplateStringsArray, ...args: (T | U)[]) => (T | U)[] +>T : any +>U : any +>W : any +>`tags ${12} ${""}` : string +>12 : 12 +>"" : "" + +const jsx4 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx4 : JSX.Element +> x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} /> : JSX.Element +>Component : (x: ComponentProps) => JSX.Element +>T : any +>U : any +>W : any +>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 + +type D = Foo; +>D : any +>Foo : Foo +>T : any +>U : any +>W : any + +// Positional after named + +const instance5 = new Foo(0, ""); +>instance5 : Foo +>new Foo(0, "") : Foo +>Foo : typeof Foo +>U : any +>0 : 0 +>"" : "" + +const result5 = foo(0, ""); +>result5 : [number, string] +>foo(0, "") : [number, string] +>foo : (x: T, y: U) => [T, U] +>U : any +>0 : 0 +>"" : "" + +const tagged5 = tag`tags ${12} ${""}`; +>tagged5 : (string | number)[] +>tag`tags ${12} ${""}` : (string | number)[] +>tag : (x: TemplateStringsArray, ...args: (T | U)[]) => (T | U)[] +>U : any +>`tags ${12} ${""}` : string +>12 : 12 +>"" : "" + +const jsx5 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx5 : JSX.Element +> x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} /> : JSX.Element +>Component : (x: ComponentProps) => JSX.Element +>U : any +>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 + +type E = Foo; +>E : Foo +>Foo : Foo +>U : any + +// Typespace only - does not provide enough arguments +type F = Foo; +>F : any +>Foo : Foo +>U : any + diff --git a/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentsComplexExamples.errors.txt b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentsComplexExamples.errors.txt new file mode 100644 index 0000000000000..3ddcd29177ef6 --- /dev/null +++ b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentsComplexExamples.errors.txt @@ -0,0 +1,73 @@ +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts(2,58): error TS2304: Cannot find name 'A'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts(8,49): error TS2345: Argument of type '{ a: ("x" | "y")[]; }' is not assignable to parameter of type '{ a?: "z"[]; b?: "z"[]; }'. + Types of property 'a' are incompatible. + Type '("x" | "y")[]' is not assignable to type '"z"[]'. + Type '"x" | "y"' is not assignable to type '"z"'. + Type '"x"' is not assignable to type '"z"'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts(14,55): error TS2345: Argument of type '{ b: ("z" | "x" | "y")[]; }' is not assignable to parameter of type '{ a?: ("x" | "y")[]; b?: ("x" | "y")[]; }'. + Types of property 'b' are incompatible. + Type '("z" | "x" | "y")[]' is not assignable to type '("x" | "y")[]'. + Type '"z" | "x" | "y"' is not assignable to type '"x" | "y"'. + Type '"z"' is not assignable to type '"x" | "y"'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts(22,50): error TS2345: Argument of type '{ c: "y"[]; }' is not assignable to parameter of type '{ a?: "x"[]; b?: "x"[]; c?: "x"[]; }'. + Types of property 'c' are incompatible. + Type '"y"[]' is not assignable to type '"x"[]'. + Type '"y"' is not assignable to type '"x"'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts(32,41): error TS1351: No value provided for required type argument 'R'. + + +==== tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts (5 errors) ==== + declare function testNamingOtherParameters(arg: { a?: A, b?: B }): { a: A, b: B }; + const assumingNotAllowed = testNamingOtherParameters({ a: "test" }); // Error, cannot find `A` + ~ +!!! error TS2304: Cannot find name 'A'. + + declare function stillDefaultsIfNoInference(arg: { a?: A, b?: B, c?: C, x?: X}): { a: A, b: B, c: C, x: X }; + const result1 = stillDefaultsIfNoInference ({ b: "test" }); // expect result1 type is {a: string, b: string, c: object, x: {}} + + declare function testConstraints1(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } + const expectError1 = testConstraints1 ({ a: ["x", "y"] }); + ~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ a: ("x" | "y")[]; }' is not assignable to parameter of type '{ a?: "z"[]; b?: "z"[]; }'. +!!! error TS2345: Types of property 'a' are incompatible. +!!! error TS2345: Type '("x" | "y")[]' is not assignable to type '"z"[]'. +!!! error TS2345: Type '"x" | "y"' is not assignable to type '"z"'. +!!! error TS2345: Type '"x"' is not assignable to type '"z"'. + + declare function testConstraints2(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } + const expectAllowed1 = testConstraints2 ({ a: ["x", "y"] }); // OK { a: string[], b: "x"[] } + const expectAllowed2 = testConstraints2 ({ b: ["x"] }); // OK { a: ("x" | "y")[], b: ("x" | "y")[] } + const expectAllowed3 = testConstraints2 ({ a: ["x", "y"] }); // OK - inference fails, but that just makes A = string, whcih still passes + const expectError2 = testConstraints2 ({ b: ["x", "y", "z"] }); // error "z" not in "x" | "y" + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ b: ("z" | "x" | "y")[]; }' is not assignable to parameter of type '{ a?: ("x" | "y")[]; b?: ("x" | "y")[]; }'. +!!! error TS2345: Types of property 'b' are incompatible. +!!! error TS2345: Type '("z" | "x" | "y")[]' is not assignable to type '("x" | "y")[]'. +!!! error TS2345: Type '"z" | "x" | "y"' is not assignable to type '"x" | "y"'. +!!! error TS2345: 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 ({ a: ["x"], c: ["x", "y"] }); // OK { a: ("x" | "y" | "z")[], b: ("x" | "y" | "z")[], c: ("x" | "y")[] } + + // OK because B inferred to be "x" but that conflicts with C as "x" | "y" so inference fails - A and C are provided, + // B becomes its constraint, A, or "x" | "y" | "z", and the call successfully resolves + const expectAlllowed5 = complexConstraints({b: ["x"]}); + const expectError3 = complexConstraints({c: ["y"]}); // error "y" does not extend "x" + ~~~~~~~~~~ +!!! error TS2345: Argument of type '{ c: "y"[]; }' is not assignable to parameter of type '{ a?: "x"[]; b?: "x"[]; c?: "x"[]; }'. +!!! error TS2345: Types of property 'c' are incompatible. +!!! error TS2345: Type '"y"[]' is not assignable to type '"x"[]'. +!!! error TS2345: Type '"y"' is not assignable to type '"x"'. + + type ExampleDefaults = { t: T, u: U, v: V }; + type ShouldBeAllowed = ExampleDefaults; + + type NoInferenceReturnPosition R, R = any> = R; + const expectAllowed6: NoInferenceReturnPosition string> = "test"; // R defaults to any, so this is fine + const expectAllowed7: NoInferenceReturnPosition string> = 35; // As is this + + type InferredReturnType2 R = any> = R; + const expectError4: InferredReturnType2 string> = "test"; // Didn't fulfill R, issues error + ~~~~~~~~~~~~~~~~ +!!! error TS1351: No value provided for required type argument 'R'. + \ No newline at end of file diff --git a/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentsComplexExamples.js b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentsComplexExamples.js new file mode 100644 index 0000000000000..c3a8100f72e32 --- /dev/null +++ b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentsComplexExamples.js @@ -0,0 +1,51 @@ +//// [typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts] +declare function testNamingOtherParameters(arg: { a?: A, b?: B }): { a: A, b: B }; +const assumingNotAllowed = testNamingOtherParameters({ a: "test" }); // Error, cannot find `A` + +declare function stillDefaultsIfNoInference(arg: { a?: A, b?: B, c?: C, x?: X}): { a: A, b: B, c: C, x: X }; +const result1 = stillDefaultsIfNoInference ({ b: "test" }); // expect result1 type is {a: string, b: string, c: object, x: {}} + +declare function testConstraints1(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +const expectError1 = testConstraints1 ({ a: ["x", "y"] }); + +declare function testConstraints2(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +const expectAllowed1 = testConstraints2 ({ a: ["x", "y"] }); // OK { a: string[], b: "x"[] } +const expectAllowed2 = testConstraints2 ({ b: ["x"] }); // OK { a: ("x" | "y")[], b: ("x" | "y")[] } +const expectAllowed3 = testConstraints2 ({ a: ["x", "y"] }); // OK - inference fails, but that just makes A = string, whcih still passes +const expectError2 = testConstraints2 ({ 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 ({ a: ["x"], c: ["x", "y"] }); // OK { a: ("x" | "y" | "z")[], b: ("x" | "y" | "z")[], c: ("x" | "y")[] } + +// OK because B inferred to be "x" but that conflicts with C as "x" | "y" so inference fails - A and C are provided, +// B becomes its constraint, A, or "x" | "y" | "z", and the call successfully resolves +const expectAlllowed5 = complexConstraints({b: ["x"]}); +const expectError3 = complexConstraints({c: ["y"]}); // error "y" does not extend "x" + +type ExampleDefaults = { t: T, u: U, v: V }; +type ShouldBeAllowed = ExampleDefaults; + +type NoInferenceReturnPosition R, R = any> = R; +const expectAllowed6: NoInferenceReturnPosition string> = "test"; // R defaults to any, so this is fine +const expectAllowed7: NoInferenceReturnPosition string> = 35; // As is this + +type InferredReturnType2 R = any> = R; +const expectError4: InferredReturnType2 string> = "test"; // Didn't fulfill R, issues error + + +//// [typeArgumentListsWithNamedTypeArgumentsComplexExamples.js] +var assumingNotAllowed = testNamingOtherParameters({ a: "test" }); // Error, cannot find `A` +var result1 = stillDefaultsIfNoInference({ b: "test" }); // expect result1 type is {a: string, b: string, c: object, x: {}} +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 expectAllowed3 = testConstraints2({ a: ["x", "y"] }); // OK - inference fails, but that just makes A = string, whcih still passes +var expectError2 = 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")[] } +// OK because B inferred to be "x" but that conflicts with C as "x" | "y" so inference fails - A and C are provided, +// B becomes its constraint, A, or "x" | "y" | "z", and the call successfully resolves +var expectAlllowed5 = complexConstraints({ b: ["x"] }); +var expectError3 = complexConstraints({ c: ["y"] }); // error "y" does not extend "x" +var expectAllowed6 = "test"; // R defaults to any, so this is fine +var expectAllowed7 = 35; // As is this +var expectError4 = "test"; // Didn't fulfill R, issues error diff --git a/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentsComplexExamples.symbols b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentsComplexExamples.symbols new file mode 100644 index 0000000000000..d82fdf936175b --- /dev/null +++ b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentsComplexExamples.symbols @@ -0,0 +1,192 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts === +declare function testNamingOtherParameters(arg: { a?: A, b?: B }): { a: A, b: B }; +>testNamingOtherParameters : Symbol(testNamingOtherParameters, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 0, 0)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 0, 43)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 0, 51)) +>arg : Symbol(arg, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 0, 61)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 0, 67)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 0, 43)) +>b : Symbol(b, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 0, 74)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 0, 51)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 0, 86)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 0, 43)) +>b : Symbol(b, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 0, 92)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 0, 51)) + +const assumingNotAllowed = testNamingOtherParameters({ a: "test" }); // Error, cannot find `A` +>assumingNotAllowed : Symbol(assumingNotAllowed, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 1, 5)) +>testNamingOtherParameters : Symbol(testNamingOtherParameters, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 0, 0)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 1, 61)) + +declare function stillDefaultsIfNoInference(arg: { a?: A, b?: B, c?: C, x?: X}): { a: A, b: B, c: C, x: X }; +>stillDefaultsIfNoInference : Symbol(stillDefaultsIfNoInference, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 1, 75)) +>X : Symbol(X, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 44)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 46)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 58)) +>C : Symbol(C, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 69)) +>arg : Symbol(arg, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 81)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 87)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 46)) +>b : Symbol(b, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 94)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 58)) +>c : Symbol(c, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 101)) +>C : Symbol(C, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 69)) +>x : Symbol(x, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 108)) +>X : Symbol(X, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 44)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 119)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 46)) +>b : Symbol(b, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 125)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 58)) +>c : Symbol(c, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 131)) +>C : Symbol(C, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 69)) +>x : Symbol(x, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 137)) +>X : Symbol(X, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 3, 44)) + +const result1 = stillDefaultsIfNoInference ({ b: "test" }); // expect result1 type is {a: string, b: string, c: object, x: {}} +>result1 : Symbol(result1, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 4, 5)) +>stillDefaultsIfNoInference : Symbol(stillDefaultsIfNoInference, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 1, 75)) +>b : Symbol(b, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 4, 57)) + +declare function testConstraints1(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +>testConstraints1 : Symbol(testConstraints1, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 4, 71)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 6, 34)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 6, 46)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 6, 46)) +>arg : Symbol(arg, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 6, 65)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 6, 72)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 6, 34)) +>b : Symbol(b, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 6, 81)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 6, 46)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 6, 95)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 6, 34)) +>b : Symbol(b, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 6, 103)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 6, 46)) + +const expectError1 = testConstraints1 ({ a: ["x", "y"] }); +>expectError1 : Symbol(expectError1, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 7, 5)) +>testConstraints1 : Symbol(testConstraints1, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 4, 71)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 7, 49)) + +declare function testConstraints2(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +>testConstraints2 : Symbol(testConstraints2, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 7, 67)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 9, 34)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 9, 51)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 9, 34)) +>arg : Symbol(arg, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 9, 65)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 9, 72)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 9, 34)) +>b : Symbol(b, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 9, 81)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 9, 51)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 9, 95)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 9, 34)) +>b : Symbol(b, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 9, 103)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 9, 51)) + +const expectAllowed1 = testConstraints2 ({ a: ["x", "y"] }); // OK { a: string[], b: "x"[] } +>expectAllowed1 : Symbol(expectAllowed1, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 10, 5)) +>testConstraints2 : Symbol(testConstraints2, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 7, 67)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 10, 51)) + +const expectAllowed2 = testConstraints2 ({ b: ["x"] }); // OK { a: ("x" | "y")[], b: ("x" | "y")[] } +>expectAllowed2 : Symbol(expectAllowed2, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 11, 5)) +>testConstraints2 : Symbol(testConstraints2, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 7, 67)) +>b : Symbol(b, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 11, 57)) + +const expectAllowed3 = testConstraints2 ({ a: ["x", "y"] }); // OK - inference fails, but that just makes A = string, whcih still passes +>expectAllowed3 : Symbol(expectAllowed3, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 12, 5)) +>testConstraints2 : Symbol(testConstraints2, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 7, 67)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 12, 51)) + +const expectError2 = testConstraints2 ({ b: ["x", "y", "z"] }); // error "z" not in "x" | "y" +>expectError2 : Symbol(expectError2, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 13, 5)) +>testConstraints2 : Symbol(testConstraints2, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 7, 67)) +>b : Symbol(b, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 13, 55)) + +declare function complexConstraints(arg: { a?: A[], b?: B[], c?: C[] }): { a: A[], b: B[], c: C[] }; +>complexConstraints : Symbol(complexConstraints, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 13, 78)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 36)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 53)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 36)) +>C : Symbol(C, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 66)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 53)) +>arg : Symbol(arg, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 80)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 86)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 36)) +>b : Symbol(b, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 95)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 53)) +>c : Symbol(c, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 104)) +>C : Symbol(C, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 66)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 118)) +>A : Symbol(A, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 36)) +>b : Symbol(b, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 126)) +>B : Symbol(B, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 53)) +>c : Symbol(c, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 134)) +>C : Symbol(C, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 15, 66)) + +const expectAllowed4 = complexConstraints ({ a: ["x"], c: ["x", "y"] }); // OK { a: ("x" | "y" | "z")[], b: ("x" | "y" | "z")[], c: ("x" | "y")[] } +>expectAllowed4 : Symbol(expectAllowed4, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 16, 5)) +>complexConstraints : Symbol(complexConstraints, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 13, 78)) +>a : Symbol(a, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 16, 65)) +>c : Symbol(c, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 16, 75)) + +// OK because B inferred to be "x" but that conflicts with C as "x" | "y" so inference fails - A and C are provided, +// B becomes its constraint, A, or "x" | "y" | "z", and the call successfully resolves +const expectAlllowed5 = complexConstraints({b: ["x"]}); +>expectAlllowed5 : Symbol(expectAlllowed5, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 20, 5)) +>complexConstraints : Symbol(complexConstraints, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 13, 78)) +>b : Symbol(b, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 20, 80)) + +const expectError3 = complexConstraints({c: ["y"]}); // error "y" does not extend "x" +>expectError3 : Symbol(expectError3, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 21, 5)) +>complexConstraints : Symbol(complexConstraints, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 13, 78)) +>c : Symbol(c, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 21, 50)) + +type ExampleDefaults = { t: T, u: U, v: V }; +>ExampleDefaults : Symbol(ExampleDefaults, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 21, 61)) +>T : Symbol(T, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 23, 21)) +>U : Symbol(U, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 23, 29)) +>V : Symbol(V, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 23, 38)) +>t : Symbol(t, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 23, 69)) +>T : Symbol(T, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 23, 21)) +>u : Symbol(u, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 23, 75)) +>U : Symbol(U, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 23, 29)) +>v : Symbol(v, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 23, 81)) +>V : Symbol(V, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 23, 38)) + +type ShouldBeAllowed = ExampleDefaults; +>ShouldBeAllowed : Symbol(ShouldBeAllowed, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 23, 89)) +>S : Symbol(S, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 24, 21)) +>V : Symbol(V, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 24, 38)) +>S : Symbol(S, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 24, 21)) +>S : Symbol(S, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 24, 21)) +>ExampleDefaults : Symbol(ExampleDefaults, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 21, 61)) +>V : Symbol(V, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 24, 38)) + +type NoInferenceReturnPosition R, R = any> = R; +>NoInferenceReturnPosition : Symbol(NoInferenceReturnPosition, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 24, 93)) +>F : Symbol(F, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 26, 31)) +>args : Symbol(args, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 26, 42)) +>R : Symbol(R, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 26, 63)) +>R : Symbol(R, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 26, 63)) +>R : Symbol(R, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 26, 63)) + +const expectAllowed6: NoInferenceReturnPosition string> = "test"; // R defaults to any, so this is fine +>expectAllowed6 : Symbol(expectAllowed6, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 27, 5)) +>NoInferenceReturnPosition : Symbol(NoInferenceReturnPosition, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 24, 93)) + +const expectAllowed7: NoInferenceReturnPosition string> = 35; // As is this +>expectAllowed7 : Symbol(expectAllowed7, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 28, 5)) +>NoInferenceReturnPosition : Symbol(NoInferenceReturnPosition, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 24, 93)) + +type InferredReturnType2 R = any> = R; +>InferredReturnType2 : Symbol(InferredReturnType2, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 28, 71)) +>R : Symbol(R, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 30, 25)) +>F : Symbol(F, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 30, 27)) +>args : Symbol(args, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 30, 39)) +>R : Symbol(R, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 30, 25)) +>R : Symbol(R, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 30, 25)) + +const expectError4: InferredReturnType2 string> = "test"; // Didn't fulfill R, issues error +>expectError4 : Symbol(expectError4, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 31, 5)) +>InferredReturnType2 : Symbol(InferredReturnType2, Decl(typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts, 28, 71)) + diff --git a/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentsComplexExamples.types b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentsComplexExamples.types new file mode 100644 index 0000000000000..9f0ea69cf6db9 --- /dev/null +++ b/tests/baselines/reference/typeArgumentListsWithNamedTypeArgumentsComplexExamples.types @@ -0,0 +1,258 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts === +declare function testNamingOtherParameters(arg: { a?: A, b?: B }): { a: A, b: B }; +>testNamingOtherParameters : (arg: { a?: A; b?: B; }) => { a: A; b: B; } +>A : A +>B : B +>arg : { a?: A; b?: B; } +>a : A +>A : A +>b : B +>B : B +>a : A +>A : A +>b : B +>B : B + +const assumingNotAllowed = testNamingOtherParameters({ a: "test" }); // Error, cannot find `A` +>assumingNotAllowed : { a: string; b: any; } +>testNamingOtherParameters({ a: "test" }) : { a: string; b: any; } +>testNamingOtherParameters : (arg: { a?: A; b?: B; }) => { a: A; b: B; } +>B : any +>A : No type information available! +>{ a: "test" } : { a: string; } +>a : string +>"test" : "test" + +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; } +>X : X +>A : A +>B : B +>C : C +>arg : { a?: A; b?: B; c?: C; x?: X; } +>a : A +>A : A +>b : B +>B : B +>c : C +>C : C +>x : X +>X : X +>a : A +>A : A +>b : B +>B : B +>c : C +>C : C +>x : X +>X : X + +const result1 = stillDefaultsIfNoInference ({ b: "test" }); // expect result1 type is {a: string, b: string, c: object, x: {}} +>result1 : { a: string; b: string; c: object; x: {}; } +>stillDefaultsIfNoInference ({ b: "test" }) : { a: string; b: string; c: object; x: {}; } +>stillDefaultsIfNoInference : (arg: { a?: A; b?: B; c?: C; x?: X; }) => { a: A; b: B; c: C; x: X; } +>C : any +>{ b: "test" } : { b: string; } +>b : string +>"test" : "test" + +declare function testConstraints1(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +>testConstraints1 : (arg?: { a?: A[]; b?: B[]; }) => { a: A[]; b: B[]; } +>A : A +>B : B +>B : B +>arg : { a?: A[]; b?: B[]; } +>a : A[] +>A : A +>b : B[] +>B : B +>a : A[] +>A : A +>b : B[] +>B : B + +const expectError1 = testConstraints1 ({ a: ["x", "y"] }); +>expectError1 : any +>testConstraints1 ({ a: ["x", "y"] }) : any +>testConstraints1 : (arg?: { a?: A[]; b?: B[]; }) => { a: A[]; b: B[]; } +>B : any +>{ 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[]; } +>A : A +>B : B +>A : A +>arg : { a?: A[]; b?: B[]; } +>a : A[] +>A : A +>b : B[] +>B : B +>a : A[] +>A : A +>b : B[] +>B : B + +const expectAllowed1 = testConstraints2 ({ a: ["x", "y"] }); // OK { a: string[], b: "x"[] } +>expectAllowed1 : { a: ("x" | "y")[]; b: "x"[]; } +>testConstraints2 ({ a: ["x", "y"] }) : { a: ("x" | "y")[]; b: "x"[]; } +>testConstraints2 : (arg?: { a?: A[]; b?: B[]; }) => { a: A[]; b: B[]; } +>B : any +>{ a: ["x", "y"] } : { a: ("x" | "y")[]; } +>a : ("x" | "y")[] +>["x", "y"] : ("x" | "y")[] +>"x" : "x" +>"y" : "y" + +const expectAllowed2 = testConstraints2 ({ b: ["x"] }); // OK { a: ("x" | "y")[], b: ("x" | "y")[] } +>expectAllowed2 : { a: ("x" | "y")[]; b: "x"[]; } +>testConstraints2 ({ b: ["x"] }) : { a: ("x" | "y")[]; b: "x"[]; } +>testConstraints2 : (arg?: { a?: A[]; b?: B[]; }) => { a: A[]; b: B[]; } +>A : any +>{ b: ["x"] } : { b: "x"[]; } +>b : "x"[] +>["x"] : "x"[] +>"x" : "x" + +const expectAllowed3 = testConstraints2 ({ a: ["x", "y"] }); // OK - inference fails, but that just makes A = string, whcih still passes +>expectAllowed3 : { a: string[]; b: "z"[]; } +>testConstraints2 ({ a: ["x", "y"] }) : { a: string[]; b: "z"[]; } +>testConstraints2 : (arg?: { a?: A[]; b?: B[]; }) => { a: A[]; b: B[]; } +>B : any +>{ a: ["x", "y"] } : { a: string[]; } +>a : string[] +>["x", "y"] : string[] +>"x" : "x" +>"y" : "y" + +const expectError2 = testConstraints2 ({ b: ["x", "y", "z"] }); // error "z" not in "x" | "y" +>expectError2 : any +>testConstraints2 ({ b: ["x", "y", "z"] }) : any +>testConstraints2 : (arg?: { a?: A[]; b?: B[]; }) => { a: A[]; b: B[]; } +>A : any +>{ 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[]; } +>A : A +>B : B +>A : A +>C : C +>B : B +>arg : { a?: A[]; b?: B[]; c?: C[]; } +>a : A[] +>A : A +>b : B[] +>B : B +>c : C[] +>C : C +>a : A[] +>A : A +>b : B[] +>B : B +>c : C[] +>C : C + +const expectAllowed4 = complexConstraints ({ 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 ({ 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 : any +>{ 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" + +// OK because B inferred to be "x" but that conflicts with C as "x" | "y" so inference fails - A and C are provided, +// B becomes its constraint, A, or "x" | "y" | "z", and the call successfully resolves +const expectAlllowed5 = complexConstraints({b: ["x"]}); +>expectAlllowed5 : { a: ("z" | "x" | "y")[]; b: ("z" | "x" | "y")[]; c: ("x" | "y")[]; } +>complexConstraints({b: ["x"]}) : { 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 : any +>C : any +>{b: ["x"]} : { b: "x"[]; } +>b : "x"[] +>["x"] : "x"[] +>"x" : "x" + +const expectError3 = complexConstraints({c: ["y"]}); // error "y" does not extend "x" +>expectError3 : any +>complexConstraints({c: ["y"]}) : any +>complexConstraints : (arg: { a?: A[]; b?: B[]; c?: C[]; }) => { a: A[]; b: B[]; c: C[]; } +>A : any +>{c: ["y"]} : { c: string[]; } +>c : string[] +>["y"] : string[] +>"y" : "y" + +type ExampleDefaults = { t: T, u: U, v: V }; +>ExampleDefaults : ExampleDefaults +>T : T +>U : U +>V : V +>t : T +>T : T +>u : U +>U : U +>v : V +>V : V + +type ShouldBeAllowed = ExampleDefaults; +>ShouldBeAllowed : ExampleDefaults +>S : S +>V : V +>S : S +>S : S +>ExampleDefaults : ExampleDefaults +>U : any +>V : any +>V : V + +type NoInferenceReturnPosition R, R = any> = R; +>NoInferenceReturnPosition : R +>F : F +>args : any[] +>R : R +>R : R +>R : R + +const expectAllowed6: NoInferenceReturnPosition string> = "test"; // R defaults to any, so this is fine +>expectAllowed6 : any +>NoInferenceReturnPosition : R +>F : any +>"test" : "test" + +const expectAllowed7: NoInferenceReturnPosition string> = 35; // As is this +>expectAllowed7 : any +>NoInferenceReturnPosition : R +>F : any +>35 : 35 + +type InferredReturnType2 R = any> = R; +>InferredReturnType2 : R +>R : R +>F : F +>args : any[] +>R : R +>R : R + +const expectError4: InferredReturnType2 string> = "test"; // Didn't fulfill R, issues error +>expectError4 : {} +>InferredReturnType2 : R +>F : any +>"test" : "test" + diff --git a/tests/baselines/reference/typeArgumentListsWithnamedTypeArguments.js b/tests/baselines/reference/typeArgumentListsWithnamedTypeArguments.js new file mode 100644 index 0000000000000..c1aa47acb302b --- /dev/null +++ b/tests/baselines/reference/typeArgumentListsWithnamedTypeArguments.js @@ -0,0 +1,98 @@ +//// [typeArgumentListsWithnamedTypeArguments.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 ; +} + +// In order + +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())} />; + +// Out of order + +const instance2 = new Foo(0, ""); +const result2 = foo(0, ""); +const tagged2 = tag`tags ${12} ${""}`; +const jsx2 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + +// With positional + +const instance3 = new Foo(0, ""); +const result3 = foo(0, ""); +const tagged3 = tag`tags ${12} ${""}`; +const jsx3 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + +// With partial inference + +const instance4 = new Foo(0, ""); +const result4 = foo(0, ""); +const tagged4 = tag`tags ${12} ${""}`; +const jsx4 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + + +//// [typeArgumentListsWithnamedTypeArguments.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); +} +// In order +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()); } }); +// Out of order +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()); } }); +// With positional +var instance3 = new Foo(0, ""); +var result3 = foo(0, ""); +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()); } }); +// With partial inference +var instance4 = new Foo(0, ""); +var result4 = foo(0, ""); +var tagged4 = tag(__makeTemplateObject(["tags ", " ", ""], ["tags ", " ", ""]), 12, ""); +var jsx4 = React.createElement(Component, { x: 12, y: "", cb: function (props) { return void (props.x.toFixed() + props.y.toUpperCase()); } }); diff --git a/tests/baselines/reference/typeArgumentListsWithnamedTypeArguments.symbols b/tests/baselines/reference/typeArgumentListsWithnamedTypeArguments.symbols new file mode 100644 index 0000000000000..b322cf3f32b98 --- /dev/null +++ b/tests/baselines/reference/typeArgumentListsWithnamedTypeArguments.symbols @@ -0,0 +1,213 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithnamedTypeArguments.tsx === +declare module JSX { +>JSX : Symbol(JSX, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 0, 0)) + + interface Element {} +>Element : Symbol(Element, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 0, 20)) +} +declare namespace React { +>React : Symbol(React, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 2, 1)) + + export function createElement(x: any, p: any, ...children: any[]): JSX.Element; +>createElement : Symbol(createElement, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 3, 25)) +>x : Symbol(x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 4, 34)) +>p : Symbol(p, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 4, 41)) +>children : Symbol(children, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 4, 49)) +>JSX : Symbol(JSX, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 0, 0)) +>Element : Symbol(JSX.Element, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 0, 20)) +} + +class Foo { +>Foo : Symbol(Foo, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 5, 1)) +>T : Symbol(T, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 7, 10)) +>U : Symbol(U, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 7, 12)) + + constructor(public prop1: T, public prop2: U) {} +>prop1 : Symbol(Foo.prop1, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 8, 16)) +>T : Symbol(T, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 7, 10)) +>prop2 : Symbol(Foo.prop2, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 8, 32)) +>U : Symbol(U, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 7, 12)) +} + +function foo(x: T, y: U): [T, U] { return [x, y]; } +>foo : Symbol(foo, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 9, 1)) +>T : Symbol(T, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 13)) +>U : Symbol(U, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 15)) +>x : Symbol(x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 19)) +>T : Symbol(T, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 13)) +>y : Symbol(y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 24)) +>U : Symbol(U, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 15)) +>T : Symbol(T, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 13)) +>U : Symbol(U, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 15)) +>x : Symbol(x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 19)) +>y : Symbol(y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 24)) + +function tag(x: TemplateStringsArray, ...args: (T | U)[]) { return args; } +>tag : Symbol(tag, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 57)) +>T : Symbol(T, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 13, 13)) +>U : Symbol(U, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 13, 15)) +>x : Symbol(x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 13, 19)) +>TemplateStringsArray : Symbol(TemplateStringsArray, Decl(lib.d.ts, --, --)) +>args : Symbol(args, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 13, 43)) +>T : Symbol(T, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 13, 13)) +>U : Symbol(U, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 13, 15)) +>args : Symbol(args, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 13, 43)) + +interface ComponentProps { +>ComponentProps : Symbol(ComponentProps, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 13, 80)) +>T : Symbol(T, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 15, 25)) +>U : Symbol(U, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 15, 27)) + + x: T; +>x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 15, 32)) +>T : Symbol(T, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 15, 25)) + + y: U; +>y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 16, 9)) +>U : Symbol(U, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 15, 27)) + + cb(props: this): void; +>cb : Symbol(ComponentProps.cb, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 17, 9)) +>props : Symbol(props, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 18, 7)) +} + +function Component(x: ComponentProps) { +>Component : Symbol(Component, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 19, 1)) +>T : Symbol(T, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 21, 19)) +>U : Symbol(U, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 21, 21)) +>x : Symbol(x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 21, 25)) +>ComponentProps : Symbol(ComponentProps, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 13, 80)) +>T : Symbol(T, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 21, 19)) +>U : Symbol(U, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 21, 21)) + + return ; +} + +// In order + +const instance1 = new Foo(0, ""); +>instance1 : Symbol(instance1, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 27, 5)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 5, 1)) + +const result1 = foo(0, ""); +>result1 : Symbol(result1, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 28, 5)) +>foo : Symbol(foo, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 9, 1)) + +const tagged1 = tag`tags ${12} ${""}`; +>tagged1 : Symbol(tagged1, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 29, 5)) +>tag : Symbol(tag, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 57)) + +const jsx1 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx1 : Symbol(jsx1, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 30, 5)) +>Component : Symbol(Component, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 19, 1)) +>x : Symbol(x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 30, 47)) +>y : Symbol(y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 30, 54)) +>cb : Symbol(cb, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 30, 59)) +>props : Symbol(props, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 30, 64)) +>props.x.toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 15, 32)) +>props : Symbol(props, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 30, 64)) +>x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 15, 32)) +>toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.y.toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) +>props.y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 16, 9)) +>props : Symbol(props, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 30, 64)) +>y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 16, 9)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) + +// Out of order + +const instance2 = new Foo(0, ""); +>instance2 : Symbol(instance2, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 34, 5)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 5, 1)) + +const result2 = foo(0, ""); +>result2 : Symbol(result2, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 35, 5)) +>foo : Symbol(foo, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 9, 1)) + +const tagged2 = tag`tags ${12} ${""}`; +>tagged2 : Symbol(tagged2, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 36, 5)) +>tag : Symbol(tag, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 57)) + +const jsx2 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx2 : Symbol(jsx2, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 37, 5)) +>Component : Symbol(Component, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 19, 1)) +>x : Symbol(x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 37, 47)) +>y : Symbol(y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 37, 54)) +>cb : Symbol(cb, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 37, 59)) +>props : Symbol(props, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 37, 64)) +>props.x.toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 15, 32)) +>props : Symbol(props, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 37, 64)) +>x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 15, 32)) +>toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.y.toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) +>props.y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 16, 9)) +>props : Symbol(props, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 37, 64)) +>y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 16, 9)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) + +// With positional + +const instance3 = new Foo(0, ""); +>instance3 : Symbol(instance3, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 41, 5)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 5, 1)) + +const result3 = foo(0, ""); +>result3 : Symbol(result3, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 42, 5)) +>foo : Symbol(foo, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 9, 1)) + +const tagged3 = tag`tags ${12} ${""}`; +>tagged3 : Symbol(tagged3, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 43, 5)) +>tag : Symbol(tag, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 57)) + +const jsx3 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx3 : Symbol(jsx3, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 44, 5)) +>Component : Symbol(Component, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 19, 1)) +>x : Symbol(x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 44, 43)) +>y : Symbol(y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 44, 50)) +>cb : Symbol(cb, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 44, 55)) +>props : Symbol(props, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 44, 60)) +>props.x.toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 15, 32)) +>props : Symbol(props, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 44, 60)) +>x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 15, 32)) +>toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.y.toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) +>props.y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 16, 9)) +>props : Symbol(props, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 44, 60)) +>y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 16, 9)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) + +// With partial inference + +const instance4 = new Foo(0, ""); +>instance4 : Symbol(instance4, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 48, 5)) +>Foo : Symbol(Foo, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 5, 1)) + +const result4 = foo(0, ""); +>result4 : Symbol(result4, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 49, 5)) +>foo : Symbol(foo, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 9, 1)) + +const tagged4 = tag`tags ${12} ${""}`; +>tagged4 : Symbol(tagged4, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 50, 5)) +>tag : Symbol(tag, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 11, 57)) + +const jsx4 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx4 : Symbol(jsx4, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 51, 5)) +>Component : Symbol(Component, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 19, 1)) +>x : Symbol(x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 51, 35)) +>y : Symbol(y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 51, 42)) +>cb : Symbol(cb, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 51, 47)) +>props : Symbol(props, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 51, 52)) +>props.x.toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 15, 32)) +>props : Symbol(props, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 51, 52)) +>x : Symbol(ComponentProps.x, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 15, 32)) +>toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) +>props.y.toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) +>props.y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 16, 9)) +>props : Symbol(props, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 51, 52)) +>y : Symbol(ComponentProps.y, Decl(typeArgumentListsWithnamedTypeArguments.tsx, 16, 9)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.d.ts, --, --)) + diff --git a/tests/baselines/reference/typeArgumentListsWithnamedTypeArguments.types b/tests/baselines/reference/typeArgumentListsWithnamedTypeArguments.types new file mode 100644 index 0000000000000..d78e3d5649ad9 --- /dev/null +++ b/tests/baselines/reference/typeArgumentListsWithnamedTypeArguments.types @@ -0,0 +1,313 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithnamedTypeArguments.tsx === +declare module JSX { +>JSX : any + + interface Element {} +>Element : 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 +>Element : JSX.Element +} + +class Foo { +>Foo : Foo +>T : T +>U : U + + constructor(public prop1: T, public prop2: U) {} +>prop1 : T +>T : T +>prop2 : U +>U : U +} + +function foo(x: T, y: U): [T, U] { return [x, y]; } +>foo : (x: T, y: U) => [T, U] +>T : T +>U : U +>x : T +>T : T +>y : U +>U : U +>T : T +>U : 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)[] +>T : T +>U : U +>x : TemplateStringsArray +>TemplateStringsArray : TemplateStringsArray +>args : (T | U)[] +>T : T +>U : U +>args : (T | U)[] + +interface ComponentProps { +>ComponentProps : ComponentProps +>T : T +>U : U + + x: T; +>x : T +>T : T + + y: U; +>y : U +>U : U + + cb(props: this): void; +>cb : (props: this) => void +>props : this +} + +function Component(x: ComponentProps) { +>Component : (x: ComponentProps) => JSX.Element +>T : T +>U : U +>x : ComponentProps +>ComponentProps : ComponentProps +>T : T +>U : U + + return ; +> : JSX.Element +>h : any +>h : any +} + +// In order + +const instance1 = new Foo(0, ""); +>instance1 : Foo +>new Foo(0, "") : Foo +>Foo : typeof Foo +>T : any +>U : any +>0 : 0 +>"" : "" + +const result1 = foo(0, ""); +>result1 : [number, string] +>foo(0, "") : [number, string] +>foo : (x: T, y: U) => [T, U] +>T : any +>U : any +>0 : 0 +>"" : "" + +const tagged1 = tag`tags ${12} ${""}`; +>tagged1 : (string | number)[] +>tag`tags ${12} ${""}` : (string | number)[] +>tag : (x: TemplateStringsArray, ...args: (T | U)[]) => (T | U)[] +>T : any +>U : any +>`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 +>T : any +>U : any +>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 + +// Out of order + +const instance2 = new Foo(0, ""); +>instance2 : Foo +>new Foo(0, "") : Foo +>Foo : typeof Foo +>U : any +>T : any +>0 : 0 +>"" : "" + +const result2 = foo(0, ""); +>result2 : [number, string] +>foo(0, "") : [number, string] +>foo : (x: T, y: U) => [T, U] +>U : any +>T : any +>0 : 0 +>"" : "" + +const tagged2 = tag`tags ${12} ${""}`; +>tagged2 : (string | number)[] +>tag`tags ${12} ${""}` : (string | number)[] +>tag : (x: TemplateStringsArray, ...args: (T | U)[]) => (T | U)[] +>U : any +>T : any +>`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 +>U : any +>T : any +>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 + +// With positional + +const instance3 = new Foo(0, ""); +>instance3 : Foo +>new Foo(0, "") : Foo +>Foo : typeof Foo +>U : any +>0 : 0 +>"" : "" + +const result3 = foo(0, ""); +>result3 : [number, string] +>foo(0, "") : [number, string] +>foo : (x: T, y: U) => [T, U] +>U : any +>0 : 0 +>"" : "" + +const tagged3 = tag`tags ${12} ${""}`; +>tagged3 : (string | number)[] +>tag`tags ${12} ${""}` : (string | number)[] +>tag : (x: TemplateStringsArray, ...args: (T | U)[]) => (T | U)[] +>U : any +>`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 +>U : any +>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 + +// With partial inference + +const instance4 = new Foo(0, ""); +>instance4 : Foo +>new Foo(0, "") : Foo +>Foo : typeof Foo +>U : any +>0 : 0 +>"" : "" + +const result4 = foo(0, ""); +>result4 : [number, string] +>foo(0, "") : [number, string] +>foo : (x: T, y: U) => [T, U] +>U : any +>0 : 0 +>"" : "" + +const tagged4 = tag`tags ${12} ${""}`; +>tagged4 : (string | number)[] +>tag`tags ${12} ${""}` : (string | number)[] +>tag : (x: TemplateStringsArray, ...args: (T | U)[]) => (T | U)[] +>U : any +>`tags ${12} ${""}` : string +>12 : 12 +>"" : "" + +const jsx4 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +>jsx4 : JSX.Element +> x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} /> : JSX.Element +>Component : (x: ComponentProps) => JSX.Element +>U : any +>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 + diff --git a/tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListWithNamedTypeArgumentsAndDefaults.ts b/tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListWithNamedTypeArgumentsAndDefaults.ts new file mode 100644 index 0000000000000..d58130c2b2477 --- /dev/null +++ b/tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListWithNamedTypeArgumentsAndDefaults.ts @@ -0,0 +1,8 @@ +class Foo { + constructor(public a?: A, public b?: B) {} +} + +const x = new Foo(); +x.a.x; +x.a.y; +x.b; diff --git a/tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx b/tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx new file mode 100644 index 0000000000000..5cd1dedc57c0d --- /dev/null +++ b/tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentErrors.tsx @@ -0,0 +1,68 @@ +// @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 ; +} + +// Does not reference valid param + +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())} />; +type A = Foo; + +// Duplicates positional + +const instance2 = new Foo(0, ""); +const result2 = foo(0, ""); +const tagged2 = tag`tags ${12} ${""}`; +const jsx2 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +type B = Foo; + +// Duplicates other named + +const instance3 = new Foo(0, ""); +const result3 = foo(0, ""); +const tagged3 = tag`tags ${12} ${""}`; +const jsx3 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +type C = Foo; + +// Too many arguments + +const instance4 = new Foo(0, ""); +const result4 = foo(0, ""); +const tagged4 = tag`tags ${12} ${""}`; +const jsx4 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +type D = Foo; + +// Positional after named + +const instance5 = new Foo(0, ""); +const result5 = foo(0, ""); +const tagged5 = tag`tags ${12} ${""}`; +const jsx5 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; +type E = Foo; + +// Typespace only - does not provide enough arguments +type F = Foo; diff --git a/tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts b/tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts new file mode 100644 index 0000000000000..ef6e9ac6bb0da --- /dev/null +++ b/tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithNamedTypeArgumentsComplexExamples.ts @@ -0,0 +1,32 @@ +declare function testNamingOtherParameters(arg: { a?: A, b?: B }): { a: A, b: B }; +const assumingNotAllowed = testNamingOtherParameters({ a: "test" }); // Error, cannot find `A` + +declare function stillDefaultsIfNoInference(arg: { a?: A, b?: B, c?: C, x?: X}): { a: A, b: B, c: C, x: X }; +const result1 = stillDefaultsIfNoInference ({ b: "test" }); // expect result1 type is {a: string, b: string, c: object, x: {}} + +declare function testConstraints1(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +const expectError1 = testConstraints1 ({ a: ["x", "y"] }); + +declare function testConstraints2(arg?: { a?: A[], b?: B[] }): { a: A[], b: B[] } +const expectAllowed1 = testConstraints2 ({ a: ["x", "y"] }); // OK { a: string[], b: "x"[] } +const expectAllowed2 = testConstraints2 ({ b: ["x"] }); // OK { a: ("x" | "y")[], b: ("x" | "y")[] } +const expectAllowed3 = testConstraints2 ({ a: ["x", "y"] }); // OK - inference fails, but that just makes A = string, whcih still passes +const expectError2 = testConstraints2 ({ 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 ({ a: ["x"], c: ["x", "y"] }); // OK { a: ("x" | "y" | "z")[], b: ("x" | "y" | "z")[], c: ("x" | "y")[] } + +// OK because B inferred to be "x" but that conflicts with C as "x" | "y" so inference fails - A and C are provided, +// B becomes its constraint, A, or "x" | "y" | "z", and the call successfully resolves +const expectAlllowed5 = complexConstraints({b: ["x"]}); +const expectError3 = complexConstraints({c: ["y"]}); // error "y" does not extend "x" + +type ExampleDefaults = { t: T, u: U, v: V }; +type ShouldBeAllowed = ExampleDefaults; + +type NoInferenceReturnPosition R, R = any> = R; +const expectAllowed6: NoInferenceReturnPosition string> = "test"; // R defaults to any, so this is fine +const expectAllowed7: NoInferenceReturnPosition string> = 35; // As is this + +type InferredReturnType2 R = any> = R; +const expectError4: InferredReturnType2 string> = "test"; // Didn't fulfill R, issues error diff --git a/tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithnamedTypeArguments.tsx b/tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithnamedTypeArguments.tsx new file mode 100644 index 0000000000000..2f2ef5536764d --- /dev/null +++ b/tests/cases/conformance/types/typeParameters/typeArgumentLists/typeArgumentListsWithNamedTypeArguments/typeArgumentListsWithnamedTypeArguments.tsx @@ -0,0 +1,53 @@ +// @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 ; +} + +// In order + +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())} />; + +// Out of order + +const instance2 = new Foo(0, ""); +const result2 = foo(0, ""); +const tagged2 = tag`tags ${12} ${""}`; +const jsx2 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + +// With positional + +const instance3 = new Foo(0, ""); +const result3 = foo(0, ""); +const tagged3 = tag`tags ${12} ${""}`; +const jsx3 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />; + +// With partial inference + +const instance4 = new Foo(0, ""); +const result4 = foo(0, ""); +const tagged4 = tag`tags ${12} ${""}`; +const jsx4 = x={12} y="" cb={props => void (props.x.toFixed() + props.y.toUpperCase())} />;