diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 9b96b78a4d3..d196d8add4d 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -101,6 +101,7 @@ namespace ts { HasLocals = 1 << 5, IsInterface = 1 << 6, IsObjectLiteralOrClassExpressionMethod = 1 << 7, + IsInferenceContainer = 1 << 8, } const binder = createBinder(); @@ -119,6 +120,7 @@ namespace ts { let parent: Node; let container: Node; let blockScopeContainer: Node; + let inferenceContainer: Node; let lastContainer: Node; let seenThisKeyword: boolean; @@ -186,6 +188,7 @@ namespace ts { parent = undefined; container = undefined; blockScopeContainer = undefined; + inferenceContainer = undefined; lastContainer = undefined; seenThisKeyword = false; currentFlow = undefined; @@ -561,6 +564,13 @@ namespace ts { bindChildren(node); node.flags = seenThisKeyword ? node.flags | NodeFlags.ContainsThis : node.flags & ~NodeFlags.ContainsThis; } + else if (containerFlags & ContainerFlags.IsInferenceContainer) { + const saveInferenceContainer = inferenceContainer; + inferenceContainer = node; + node.locals = undefined; + bindChildren(node); + inferenceContainer = saveInferenceContainer; + } else { bindChildren(node); } @@ -1417,6 +1427,9 @@ namespace ts { case SyntaxKind.MappedType: return ContainerFlags.IsContainer | ContainerFlags.HasLocals; + case SyntaxKind.ConditionalType: + return ContainerFlags.IsInferenceContainer; + case SyntaxKind.SourceFile: return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals; @@ -2059,7 +2072,7 @@ namespace ts { case SyntaxKind.TypePredicate: return checkTypePredicate(node as TypePredicateNode); case SyntaxKind.TypeParameter: - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); + return bindTypeParameter(node as TypeParameterDeclaration); case SyntaxKind.Parameter: return bindParameter(node); case SyntaxKind.VariableDeclaration: @@ -2576,6 +2589,23 @@ namespace ts { : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } + function bindTypeParameter(node: TypeParameterDeclaration) { + if (node.parent.kind === SyntaxKind.InferType) { + if (inferenceContainer) { + if (!inferenceContainer.locals) { + inferenceContainer.locals = createSymbolTable(); + } + declareSymbol(inferenceContainer.locals, /*parent*/ undefined, node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); + } + else { + bindAnonymousDeclaration(node, SymbolFlags.TypeParameter, getDeclarationName(node)); + } + } + else { + declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); + } + } + // reachability checks function shouldReportErrorOnModuleDeclaration(node: ModuleDeclaration): boolean { @@ -3441,6 +3471,7 @@ namespace ts { case SyntaxKind.UnionType: case SyntaxKind.IntersectionType: case SyntaxKind.ConditionalType: + case SyntaxKind.InferType: case SyntaxKind.ParenthesizedType: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.TypeAliasDeclaration: diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6a146f7ca2e..05da314a816 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -542,6 +542,7 @@ namespace ts { const subtypeRelation = createMap(); const assignableRelation = createMap(); + const definitelyAssignableRelation = createMap(); const comparableRelation = createMap(); const identityRelation = createMap(); const enumRelation = createMap(); @@ -1188,6 +1189,11 @@ namespace ts { ); } } + else if (location.kind === SyntaxKind.ConditionalType) { + // A type parameter declared using 'infer T' in a conditional type is visible only in + // the true branch of the conditional type. + useResult = lastLocation === (location).trueType; + } if (useResult) { break loop; @@ -4677,10 +4683,14 @@ namespace ts { case SyntaxKind.TypeAliasDeclaration: case SyntaxKind.JSDocTemplateTag: case SyntaxKind.MappedType: + case SyntaxKind.ConditionalType: const outerTypeParameters = getOuterTypeParameters(node, includeThisTypes); if (node.kind === SyntaxKind.MappedType) { return append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode((node).typeParameter))); } + else if (node.kind === SyntaxKind.ConditionalType) { + return concatenate(outerTypeParameters, getInferTypeParameters(node)); + } const outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, getEffectiveTypeParameterDeclarations(node) || emptyArray); const thisType = includeThisTypes && (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || node.kind === SyntaxKind.InterfaceDeclaration) && @@ -8122,12 +8132,13 @@ namespace ts { return type.flags & TypeFlags.Substitution ? (type).typeParameter : type; } - function createConditionalType(checkType: Type, extendsType: Type, trueType: Type, falseType: Type, target: ConditionalType, mapper: TypeMapper, aliasSymbol: Symbol, aliasTypeArguments: Type[]) { + function createConditionalType(checkType: Type, extendsType: Type, trueType: Type, falseType: Type, inferTypeParameters: TypeParameter[], target: ConditionalType, mapper: TypeMapper, aliasSymbol: Symbol, aliasTypeArguments: Type[]) { const type = createType(TypeFlags.Conditional); type.checkType = checkType; type.extendsType = extendsType; type.trueType = trueType; type.falseType = falseType; + type.inferTypeParameters = inferTypeParameters; type.target = target; type.mapper = mapper; type.aliasSymbol = aliasSymbol; @@ -8135,19 +8146,41 @@ namespace ts { return type; } - function getConditionalType(checkType: Type, extendsType: Type, baseTrueType: Type, baseFalseType: Type, target: ConditionalType, mapper: TypeMapper, aliasSymbol?: Symbol, baseAliasTypeArguments?: Type[]): Type { - // Return union of trueType and falseType for any and never since they match anything - if (checkType.flags & (TypeFlags.Any | TypeFlags.Never)) { - return getUnionType([instantiateType(baseTrueType, mapper), instantiateType(baseFalseType, mapper)]); - } - // Return trueType for a definitely true extends check - if (isTypeAssignableTo(checkType, extendsType)) { - return instantiateType(baseTrueType, mapper); - } - // Return falseType for a definitely false extends check - if (!isTypeAssignableTo(instantiateType(checkType, anyMapper), instantiateType(extendsType, constraintMapper))) { + function getConditionalType(checkType: Type, baseExtendsType: Type, baseTrueType: Type, baseFalseType: Type, inferTypeParameters: TypeParameter[], target: ConditionalType, mapper: TypeMapper, aliasSymbol?: Symbol, baseAliasTypeArguments?: Type[]): Type { + // Instantiate extends type without instantiating any 'infer T' type parameters + const extendsType = instantiateType(baseExtendsType, mapper); + // Return falseType for a definitely false extends check. We check an instantations of the two + // types with type parameters mapped to any, the most permissive instantiations possible. If those + // are not related, then no instatiations will be and we can just return the false branch type. + if (!isTypeAssignableTo(getAnyInstantiation(checkType), getAnyInstantiation(extendsType))) { return instantiateType(baseFalseType, mapper); } + // The check could be true for some instantiation + let combinedMapper: TypeMapper; + if (inferTypeParameters) { + const inferences = map(inferTypeParameters, createInferenceInfo); + // We don't want inferences from constraints as they may cause us to eagerly resolve the + // conditional type instead of deferring resolution. Also, we always want strict function + // types rules (i.e. proper contravariance) for inferences. + inferTypes(inferences, checkType, extendsType, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict); + // We infer 'never' when there are no candidates for a type parameter + const inferredTypes = map(inferences, inference => getTypeFromInference(inference) || neverType); + const inferenceMapper = createTypeMapper(inferTypeParameters, inferredTypes); + combinedMapper = mapper ? combineTypeMappers(mapper, inferenceMapper) : inferenceMapper; + } + // Return union of trueType and falseType for any and never since they match anything + if (checkType.flags & TypeFlags.Any || (checkType.flags & TypeFlags.Never && !(extendsType.flags & TypeFlags.Never))) { + return getUnionType([instantiateType(baseTrueType, combinedMapper || mapper), instantiateType(baseFalseType, mapper)]); + } + // Instantiate the extends type including inferences for 'infer T' type parameters + const inferredExtendsType = combinedMapper ? instantiateType(baseExtendsType, combinedMapper) : extendsType; + // Return trueType for a definitely true extends check. The definitely assignable relation excludes + // type variable constraints from consideration. Without the definitely assignable relation, the type + // type Foo = T extends { x: string } ? string : number + // would immediately resolve to 'string' instead of being deferred. + if (checkTypeRelatedTo(checkType, inferredExtendsType, definitelyAssignableRelation, /*errorNode*/ undefined)) { + return instantiateType(baseTrueType, combinedMapper || mapper); + } // Return a deferred type for a check that is neither definitely true nor definitely false const erasedCheckType = getActualTypeParameter(checkType); const trueType = instantiateType(baseTrueType, mapper); @@ -8158,25 +8191,45 @@ namespace ts { return cached; } const result = createConditionalType(erasedCheckType, extendsType, trueType, falseType, - target, mapper, aliasSymbol, instantiateTypes(baseAliasTypeArguments, mapper)); + inferTypeParameters, target, mapper, aliasSymbol, instantiateTypes(baseAliasTypeArguments, mapper)); if (id) { conditionalTypes.set(id, result); } return result; } + function getInferTypeParameters(node: ConditionalTypeNode): TypeParameter[] { + let result: TypeParameter[]; + if (node.locals) { + node.locals.forEach(symbol => { + if (symbol.flags & SymbolFlags.TypeParameter) { + result = append(result, getDeclaredTypeOfSymbol(symbol)); + } + }); + } + return result; + } + function getTypeFromConditionalTypeNode(node: ConditionalTypeNode): Type { const links = getNodeLinks(node); if (!links.resolvedType) { links.resolvedType = getConditionalType( getTypeFromTypeNode(node.checkType), getTypeFromTypeNode(node.extendsType), getTypeFromTypeNode(node.trueType), getTypeFromTypeNode(node.falseType), - /*target*/ undefined, /*mapper*/ undefined, + getInferTypeParameters(node), /*target*/ undefined, /*mapper*/ undefined, getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node)); } return links.resolvedType; } + function getTypeFromInferTypeNode(node: InferTypeNode): Type { + const links = getNodeLinks(node); + if (!links.resolvedType) { + links.resolvedType = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter)); + } + return links.resolvedType; + } + function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node: TypeNode): Type { const links = getNodeLinks(node); if (!links.resolvedType) { @@ -8467,6 +8520,8 @@ namespace ts { return getTypeFromMappedTypeNode(node); case SyntaxKind.ConditionalType: return getTypeFromConditionalTypeNode(node); + case SyntaxKind.InferType: + return getTypeFromInferTypeNode(node); // This function assumes that an identifier or qualified name is a type expression // Callers should first ensure this by calling isTypeNode case SyntaxKind.Identifier: @@ -8564,10 +8619,6 @@ namespace ts { return type.flags & TypeFlags.TypeParameter ? anyType : type; } - function constraintMapper(type: Type) { - return type.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(type) || anyType : type; - } - function cloneTypeParameter(typeParameter: TypeParameter): TypeParameter { const result = createType(TypeFlags.TypeParameter); result.symbol = typeParameter.symbol; @@ -8770,8 +8821,8 @@ namespace ts { } function instantiateConditionalType(type: ConditionalType, mapper: TypeMapper): Type { - return getConditionalType(instantiateType(type.checkType, mapper), instantiateType(type.extendsType, mapper), - type.trueType, type.falseType, type, mapper, type.aliasSymbol, type.aliasTypeArguments); + return getConditionalType(instantiateType(type.checkType, mapper), type.extendsType, type.trueType, type.falseType, + type.inferTypeParameters, type, mapper, type.aliasSymbol, type.aliasTypeArguments); } function instantiateType(type: Type, mapper: TypeMapper): Type { @@ -8822,6 +8873,11 @@ namespace ts { return type; } + function getAnyInstantiation(type: Type) { + return type.flags & (TypeFlags.Primitive | TypeFlags.Any | TypeFlags.Never) ? type : + type.resolvedAnyInstantiation || (type.resolvedAnyInstantiation = instantiateType(type, anyMapper)); + } + function instantiateIndexInfo(info: IndexInfo, mapper: TypeMapper): IndexInfo { return info && createIndexInfo(instantiateType(info.type, mapper), info.isReadonly, info.declaration); } @@ -9249,7 +9305,7 @@ namespace ts { if (s & TypeFlags.Null && (!strictNullChecks || t & TypeFlags.Null)) return true; if (s & TypeFlags.Object && t & TypeFlags.NonPrimitive) return true; if (s & TypeFlags.UniqueESSymbol || t & TypeFlags.UniqueESSymbol) return false; - if (relation === assignableRelation || relation === comparableRelation) { + if (relation === assignableRelation || relation === definitelyAssignableRelation || relation === comparableRelation) { if (s & TypeFlags.Any) return true; // Type number or any numeric literal type is assignable to any numeric enum type or any // numeric enum literal type. This rule exists for backwards compatibility reasons because @@ -9418,7 +9474,7 @@ namespace ts { target = (target).regularType; } if (source.flags & TypeFlags.Substitution) { - source = (source).substitute; + source = relation === definitelyAssignableRelation ? (source).typeParameter : (source).substitute; } if (target.flags & TypeFlags.Substitution) { target = (target).typeParameter; @@ -9550,7 +9606,7 @@ namespace ts { function hasExcessProperties(source: FreshObjectLiteralType, target: Type, discriminant: Type | undefined, reportErrors: boolean): boolean { if (maybeTypeOfKind(target, TypeFlags.Object) && !(getObjectFlags(target) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) { const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes); - if ((relation === assignableRelation || relation === comparableRelation) && + if ((relation === assignableRelation || relation === definitelyAssignableRelation || relation === comparableRelation) && (isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))) { return false; } @@ -9819,6 +9875,10 @@ namespace ts { return result; } + function getConstraintForRelation(type: Type) { + return relation === definitelyAssignableRelation ? undefined : getConstraintOfType(type); + } + function structuredTypeRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary { let result: Ternary; let originalErrorInfo: DiagnosticMessageChain; @@ -9844,7 +9904,7 @@ namespace ts { } // A type S is assignable to keyof T if S is assignable to keyof C, where C is the // constraint of T. - const constraint = getConstraintOfType((target).type); + const constraint = getConstraintForRelation((target).type); if (constraint) { if (result = isRelatedTo(source, getIndexType(constraint), reportErrors)) { return result; @@ -9853,8 +9913,8 @@ namespace ts { } else if (target.flags & TypeFlags.IndexedAccess) { // A type S is related to a type T[K] if S is related to A[K], where K is string-like and - // A is the constraint of T. - const constraint = getConstraintOfIndexedAccess(target); + // A is the apparent type of T. + const constraint = getConstraintForRelation(target); if (constraint) { if (result = isRelatedTo(source, constraint, reportErrors)) { errorInfo = saveErrorInfo; @@ -9881,7 +9941,7 @@ namespace ts { } if (source.flags & TypeFlags.TypeParameter) { - let constraint = getConstraintOfTypeParameter(source); + let constraint = getConstraintForRelation(source); // A type parameter with no constraint is not related to the non-primitive object type. if (constraint || !(target.flags & TypeFlags.NonPrimitive)) { if (!constraint || constraint.flags & TypeFlags.Any) { @@ -9897,8 +9957,8 @@ namespace ts { } else if (source.flags & TypeFlags.IndexedAccess) { // A type S[K] is related to a type T if A[K] is related to T, where K is string-like and - // A is the constraint of S. - const constraint = getConstraintOfIndexedAccess(source); + // A is the apparent type of S. + const constraint = getConstraintForRelation(source); if (constraint) { if (result = isRelatedTo(constraint, target, reportErrors)) { errorInfo = saveErrorInfo; @@ -9916,11 +9976,13 @@ namespace ts { } } else if (source.flags & TypeFlags.Conditional) { - const constraint = getConstraintOfDistributiveConditionalType(source); - if (constraint) { - if (result = isRelatedTo(constraint, target, reportErrors)) { - errorInfo = saveErrorInfo; - return result; + if (relation !== definitelyAssignableRelation) { + const constraint = getConstraintOfDistributiveConditionalType(source); + if (constraint) { + if (result = isRelatedTo(constraint, target, reportErrors)) { + errorInfo = saveErrorInfo; + return result; + } } } if (result = isRelatedTo(getDefaultConstraintOfConditionalType(source), target, reportErrors)) { @@ -11267,9 +11329,7 @@ namespace ts { const templateType = getTemplateTypeFromMappedType(target); const inference = createInferenceInfo(typeParameter); inferTypes([inference], sourceType, templateType); - return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : - inference.contraCandidates ? getCommonSubtype(inference.contraCandidates) : - emptyObjectType; + return getTypeFromInference(inference) || emptyObjectType; } function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean) { @@ -11285,6 +11345,12 @@ namespace ts { return undefined; } + function getTypeFromInference(inference: InferenceInfo) { + return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : + inference.contraCandidates ? getIntersectionType(inference.contraCandidates) : + undefined; + } + function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) { let symbolStack: Symbol[]; let visited: Map; @@ -11444,7 +11510,9 @@ namespace ts { } } else { - source = getApparentType(source); + if (!(priority && InferencePriority.NoConstraints && source.flags & (TypeFlags.Intersection | TypeFlags.Instantiable))) { + source = getApparentType(source); + } if (source.flags & (TypeFlags.Object | TypeFlags.Intersection)) { const key = source.id + "," + target.id; if (visited && visited.get(key)) { @@ -11474,7 +11542,7 @@ namespace ts { } function inferFromContravariantTypes(source: Type, target: Type) { - if (strictFunctionTypes) { + if (strictFunctionTypes || priority & InferencePriority.AlwaysStrict) { contravariant = !contravariant; inferFromTypes(source, target); contravariant = !contravariant; @@ -20174,6 +20242,13 @@ namespace ts { forEachChild(node, checkSourceElement); } + function checkInferType(node: InferTypeNode) { + if (!findAncestor(node, n => n.parent && n.parent.kind === SyntaxKind.ConditionalType && (n.parent).extendsType === n)) { + grammarErrorOnNode(node, Diagnostics.infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type); + } + checkSourceElement(node.typeParameter); + } + function isPrivateWithinAmbient(node: Node): boolean { return hasModifier(node, ModifierFlags.Private) && !!(node.flags & NodeFlags.Ambient); } @@ -23885,6 +23960,8 @@ namespace ts { return checkTypeOperator(node); case SyntaxKind.ConditionalType: return checkConditionalType(node); + case SyntaxKind.InferType: + return checkInferType(node); case SyntaxKind.JSDocAugmentsTag: return checkJSDocAugmentsTag(node as JSDocAugmentsTag); case SyntaxKind.JSDocTypedefTag: diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index f41a485ac63..24646ff31eb 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -452,6 +452,8 @@ namespace ts { return emitIntersectionType(type); case SyntaxKind.ConditionalType: return emitConditionalType(type); + case SyntaxKind.InferType: + return emitInferType(type); case SyntaxKind.ParenthesizedType: return emitParenType(type); case SyntaxKind.TypeOperator: @@ -552,11 +554,19 @@ namespace ts { write(" extends "); emitType(node.extendsType); write(" ? "); + const prevEnclosingDeclaration = enclosingDeclaration; + enclosingDeclaration = node.trueType; emitType(node.trueType); + enclosingDeclaration = prevEnclosingDeclaration; write(" : "); emitType(node.falseType); } + function emitInferType(node: InferTypeNode) { + write("infer "); + writeTextOfNode(currentText, node.typeParameter.name); + } + function emitParenType(type: ParenthesizedTypeNode) { write("("); emitType(type.type); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6fffd576e7c..77614dd7573 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -947,6 +947,10 @@ "category": "Error", "code": 1337 }, + "'infer' declarations are only permitted in the 'extends' clause of a conditional type.": { + "category": "Error", + "code": 1338 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8cf976bf8bc..58aa2c7a563 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -602,6 +602,8 @@ namespace ts { return emitIntersectionType(node); case SyntaxKind.ConditionalType: return emitConditionalType(node); + case SyntaxKind.InferType: + return emitInferType(node); case SyntaxKind.ParenthesizedType: return emitParenthesizedType(node); case SyntaxKind.ExpressionWithTypeArguments: @@ -1194,14 +1196,26 @@ namespace ts { function emitConditionalType(node: ConditionalTypeNode) { emit(node.checkType); - write(" extends "); + writeSpace(); + writeKeyword("extends"); + writeSpace(); emit(node.extendsType); - write(" ? "); + writeSpace(); + writePunctuation("?"); + writeSpace(); emit(node.trueType); - write(" : "); + writeSpace(); + writePunctuation(":"); + writeSpace(); emit(node.falseType); } + function emitInferType(node: InferTypeNode) { + writeKeyword("infer"); + writeSpace(); + emit(node.typeParameter); + } + function emitParenthesizedType(node: ParenthesizedTypeNode) { writePunctuation("("); emit(node.type); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index d427c7c4f64..165c70b37e6 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -749,6 +749,18 @@ namespace ts { : node; } + export function createInferTypeNode(typeParameter: TypeParameterDeclaration) { + const node = createSynthesizedNode(SyntaxKind.InferType); + node.typeParameter = typeParameter; + return node; + } + + export function updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration) { + return node.typeParameter !== typeParameter + ? updateNode(createInferTypeNode(typeParameter), node) + : node; + } + export function createParenthesizedType(type: TypeNode) { const node = createSynthesizedNode(SyntaxKind.ParenthesizedType); node.type = type; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 30a132a1226..5b8504eb6dc 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -180,6 +180,8 @@ namespace ts { visitNode(cbNode, (node).extendsType) || visitNode(cbNode, (node).trueType) || visitNode(cbNode, (node).falseType); + case SyntaxKind.InferType: + return visitNode(cbNode, (node).typeParameter); case SyntaxKind.ParenthesizedType: case SyntaxKind.TypeOperator: return visitNode(cbNode, (node).type); @@ -2767,6 +2769,7 @@ namespace ts { case SyntaxKind.QuestionToken: case SyntaxKind.ExclamationToken: case SyntaxKind.DotDotDotToken: + case SyntaxKind.InferKeyword: return true; case SyntaxKind.MinusToken: return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral); @@ -2843,12 +2846,23 @@ namespace ts { return finishNode(node); } + function parseInferType(): InferTypeNode { + const node = createNode(SyntaxKind.InferType); + parseExpected(SyntaxKind.InferKeyword); + const typeParameter = createNode(SyntaxKind.TypeParameter); + typeParameter.name = parseIdentifier(); + node.typeParameter = finishNode(typeParameter); + return finishNode(node); + } + function parseTypeOperatorOrHigher(): TypeNode { const operator = token(); switch (operator) { case SyntaxKind.KeyOfKeyword: case SyntaxKind.UniqueKeyword: return parseTypeOperator(operator); + case SyntaxKind.InferKeyword: + return parseInferType(); case SyntaxKind.DotDotDotToken: { const result = createNode(SyntaxKind.JSDocVariadicType) as JSDocVariadicType; nextToken(); diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 6b0d10223fd..cdb055bb732 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -92,6 +92,7 @@ namespace ts { "implements": SyntaxKind.ImplementsKeyword, "import": SyntaxKind.ImportKeyword, "in": SyntaxKind.InKeyword, + "infer": SyntaxKind.InferKeyword, "instanceof": SyntaxKind.InstanceOfKeyword, "interface": SyntaxKind.InterfaceKeyword, "is": SyntaxKind.IsKeyword, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a3b7b5dcda3..0a1c49a93c3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -215,6 +215,7 @@ namespace ts { ConstructorKeyword, DeclareKeyword, GetKeyword, + InferKeyword, IsKeyword, KeyOfKeyword, ModuleKeyword, @@ -266,6 +267,7 @@ namespace ts { UnionType, IntersectionType, ConditionalType, + InferType, ParenthesizedType, ThisType, TypeOperator, @@ -771,7 +773,7 @@ namespace ts { export interface TypeParameterDeclaration extends NamedDeclaration { kind: SyntaxKind.TypeParameter; - parent?: DeclarationWithTypeParameters; + parent?: DeclarationWithTypeParameters | InferTypeNode; name: Identifier; constraint?: TypeNode; default?: TypeNode; @@ -1125,6 +1127,11 @@ namespace ts { falseType: TypeNode; } + export interface InferTypeNode extends TypeNode { + kind: SyntaxKind.InferType; + typeParameter: TypeParameterDeclaration; + } + export interface ParenthesizedTypeNode extends TypeNode { kind: SyntaxKind.ParenthesizedType; type: TypeNode; @@ -3556,6 +3563,8 @@ namespace ts { pattern?: DestructuringPattern; // Destructuring pattern represented by type (if any) aliasSymbol?: Symbol; // Alias associated with type aliasTypeArguments?: Type[]; // Alias type arguments (if any) + /* @internal */ + resolvedAnyInstantiation?: Type; // Instantiation with type parameters mapped to any } /* @internal */ @@ -3801,6 +3810,8 @@ namespace ts { trueType: Type; falseType: Type; /* @internal */ + inferTypeParameters: TypeParameter[]; + /* @internal */ target?: ConditionalType; /* @internal */ mapper?: TypeMapper; @@ -3876,6 +3887,8 @@ namespace ts { NakedTypeVariable = 1 << 0, // Naked type variable in union or intersection type MappedType = 1 << 1, // Reverse inference for mapped type ReturnType = 1 << 2, // Inference made from return type of generic function + NoConstraints = 1 << 3, // Don't infer from constraints of instantiable types + AlwaysStrict = 1 << 4, // Always use strict rules for contravariant inferences } export interface InferenceInfo { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 10dfe405c89..fb85f46fbd0 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4625,6 +4625,10 @@ namespace ts { return node.kind === SyntaxKind.ConditionalType; } + export function isInferTypeNode(node: Node): node is InferTypeNode { + return node.kind === SyntaxKind.InferType; + } + export function isParenthesizedTypeNode(node: Node): node is ParenthesizedTypeNode { return node.kind === SyntaxKind.ParenthesizedType; } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index db37749caea..9c1462e7ec6 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -394,6 +394,10 @@ namespace ts { visitNode((node).trueType, visitor, isTypeNode), visitNode((node).falseType, visitor, isTypeNode)); + case SyntaxKind.InferType: + return updateInferTypeNode(node, + visitNode((node).typeParameter, visitor, isTypeParameterDeclaration)); + case SyntaxKind.ParenthesizedType: return updateParenthesizedType(node, visitNode((node).type, visitor, isTypeNode)); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index aa4a2058c04..9d3000d6b60 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -187,178 +187,180 @@ declare namespace ts { ConstructorKeyword = 123, DeclareKeyword = 124, GetKeyword = 125, - IsKeyword = 126, - KeyOfKeyword = 127, - ModuleKeyword = 128, - NamespaceKeyword = 129, - NeverKeyword = 130, - ReadonlyKeyword = 131, - RequireKeyword = 132, - NumberKeyword = 133, - ObjectKeyword = 134, - SetKeyword = 135, - StringKeyword = 136, - SymbolKeyword = 137, - TypeKeyword = 138, - UndefinedKeyword = 139, - UniqueKeyword = 140, - FromKeyword = 141, - GlobalKeyword = 142, - OfKeyword = 143, - QualifiedName = 144, - ComputedPropertyName = 145, - TypeParameter = 146, - Parameter = 147, - Decorator = 148, - PropertySignature = 149, - PropertyDeclaration = 150, - MethodSignature = 151, - MethodDeclaration = 152, - Constructor = 153, - GetAccessor = 154, - SetAccessor = 155, - CallSignature = 156, - ConstructSignature = 157, - IndexSignature = 158, - TypePredicate = 159, - TypeReference = 160, - FunctionType = 161, - ConstructorType = 162, - TypeQuery = 163, - TypeLiteral = 164, - ArrayType = 165, - TupleType = 166, - UnionType = 167, - IntersectionType = 168, - ConditionalType = 169, - ParenthesizedType = 170, - ThisType = 171, - TypeOperator = 172, - IndexedAccessType = 173, - MappedType = 174, - LiteralType = 175, - ObjectBindingPattern = 176, - ArrayBindingPattern = 177, - BindingElement = 178, - ArrayLiteralExpression = 179, - ObjectLiteralExpression = 180, - PropertyAccessExpression = 181, - ElementAccessExpression = 182, - CallExpression = 183, - NewExpression = 184, - TaggedTemplateExpression = 185, - TypeAssertionExpression = 186, - ParenthesizedExpression = 187, - FunctionExpression = 188, - ArrowFunction = 189, - DeleteExpression = 190, - TypeOfExpression = 191, - VoidExpression = 192, - AwaitExpression = 193, - PrefixUnaryExpression = 194, - PostfixUnaryExpression = 195, - BinaryExpression = 196, - ConditionalExpression = 197, - TemplateExpression = 198, - YieldExpression = 199, - SpreadElement = 200, - ClassExpression = 201, - OmittedExpression = 202, - ExpressionWithTypeArguments = 203, - AsExpression = 204, - NonNullExpression = 205, - MetaProperty = 206, - TemplateSpan = 207, - SemicolonClassElement = 208, - Block = 209, - VariableStatement = 210, - EmptyStatement = 211, - ExpressionStatement = 212, - IfStatement = 213, - DoStatement = 214, - WhileStatement = 215, - ForStatement = 216, - ForInStatement = 217, - ForOfStatement = 218, - ContinueStatement = 219, - BreakStatement = 220, - ReturnStatement = 221, - WithStatement = 222, - SwitchStatement = 223, - LabeledStatement = 224, - ThrowStatement = 225, - TryStatement = 226, - DebuggerStatement = 227, - VariableDeclaration = 228, - VariableDeclarationList = 229, - FunctionDeclaration = 230, - ClassDeclaration = 231, - InterfaceDeclaration = 232, - TypeAliasDeclaration = 233, - EnumDeclaration = 234, - ModuleDeclaration = 235, - ModuleBlock = 236, - CaseBlock = 237, - NamespaceExportDeclaration = 238, - ImportEqualsDeclaration = 239, - ImportDeclaration = 240, - ImportClause = 241, - NamespaceImport = 242, - NamedImports = 243, - ImportSpecifier = 244, - ExportAssignment = 245, - ExportDeclaration = 246, - NamedExports = 247, - ExportSpecifier = 248, - MissingDeclaration = 249, - ExternalModuleReference = 250, - JsxElement = 251, - JsxSelfClosingElement = 252, - JsxOpeningElement = 253, - JsxClosingElement = 254, - JsxFragment = 255, - JsxOpeningFragment = 256, - JsxClosingFragment = 257, - JsxAttribute = 258, - JsxAttributes = 259, - JsxSpreadAttribute = 260, - JsxExpression = 261, - CaseClause = 262, - DefaultClause = 263, - HeritageClause = 264, - CatchClause = 265, - PropertyAssignment = 266, - ShorthandPropertyAssignment = 267, - SpreadAssignment = 268, - EnumMember = 269, - SourceFile = 270, - Bundle = 271, - JSDocTypeExpression = 272, - JSDocAllType = 273, - JSDocUnknownType = 274, - JSDocNullableType = 275, - JSDocNonNullableType = 276, - JSDocOptionalType = 277, - JSDocFunctionType = 278, - JSDocVariadicType = 279, - JSDocComment = 280, - JSDocTypeLiteral = 281, - JSDocTag = 282, - JSDocAugmentsTag = 283, - JSDocClassTag = 284, - JSDocParameterTag = 285, - JSDocReturnTag = 286, - JSDocTypeTag = 287, - JSDocTemplateTag = 288, - JSDocTypedefTag = 289, - JSDocPropertyTag = 290, - SyntaxList = 291, - NotEmittedStatement = 292, - PartiallyEmittedExpression = 293, - CommaListExpression = 294, - MergeDeclarationMarker = 295, - EndOfDeclarationMarker = 296, - Count = 297, + InferKeyword = 126, + IsKeyword = 127, + KeyOfKeyword = 128, + ModuleKeyword = 129, + NamespaceKeyword = 130, + NeverKeyword = 131, + ReadonlyKeyword = 132, + RequireKeyword = 133, + NumberKeyword = 134, + ObjectKeyword = 135, + SetKeyword = 136, + StringKeyword = 137, + SymbolKeyword = 138, + TypeKeyword = 139, + UndefinedKeyword = 140, + UniqueKeyword = 141, + FromKeyword = 142, + GlobalKeyword = 143, + OfKeyword = 144, + QualifiedName = 145, + ComputedPropertyName = 146, + TypeParameter = 147, + Parameter = 148, + Decorator = 149, + PropertySignature = 150, + PropertyDeclaration = 151, + MethodSignature = 152, + MethodDeclaration = 153, + Constructor = 154, + GetAccessor = 155, + 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, + ObjectBindingPattern = 178, + ArrayBindingPattern = 179, + BindingElement = 180, + ArrayLiteralExpression = 181, + ObjectLiteralExpression = 182, + PropertyAccessExpression = 183, + ElementAccessExpression = 184, + CallExpression = 185, + NewExpression = 186, + TaggedTemplateExpression = 187, + TypeAssertionExpression = 188, + ParenthesizedExpression = 189, + FunctionExpression = 190, + ArrowFunction = 191, + DeleteExpression = 192, + TypeOfExpression = 193, + VoidExpression = 194, + AwaitExpression = 195, + PrefixUnaryExpression = 196, + PostfixUnaryExpression = 197, + BinaryExpression = 198, + ConditionalExpression = 199, + TemplateExpression = 200, + YieldExpression = 201, + SpreadElement = 202, + ClassExpression = 203, + OmittedExpression = 204, + ExpressionWithTypeArguments = 205, + AsExpression = 206, + NonNullExpression = 207, + MetaProperty = 208, + TemplateSpan = 209, + SemicolonClassElement = 210, + Block = 211, + VariableStatement = 212, + EmptyStatement = 213, + ExpressionStatement = 214, + IfStatement = 215, + DoStatement = 216, + WhileStatement = 217, + ForStatement = 218, + ForInStatement = 219, + ForOfStatement = 220, + ContinueStatement = 221, + BreakStatement = 222, + ReturnStatement = 223, + WithStatement = 224, + SwitchStatement = 225, + LabeledStatement = 226, + ThrowStatement = 227, + TryStatement = 228, + DebuggerStatement = 229, + VariableDeclaration = 230, + VariableDeclarationList = 231, + FunctionDeclaration = 232, + ClassDeclaration = 233, + InterfaceDeclaration = 234, + TypeAliasDeclaration = 235, + EnumDeclaration = 236, + ModuleDeclaration = 237, + ModuleBlock = 238, + CaseBlock = 239, + NamespaceExportDeclaration = 240, + ImportEqualsDeclaration = 241, + ImportDeclaration = 242, + ImportClause = 243, + NamespaceImport = 244, + NamedImports = 245, + ImportSpecifier = 246, + ExportAssignment = 247, + ExportDeclaration = 248, + NamedExports = 249, + ExportSpecifier = 250, + MissingDeclaration = 251, + ExternalModuleReference = 252, + JsxElement = 253, + JsxSelfClosingElement = 254, + JsxOpeningElement = 255, + JsxClosingElement = 256, + JsxFragment = 257, + JsxOpeningFragment = 258, + JsxClosingFragment = 259, + JsxAttribute = 260, + JsxAttributes = 261, + JsxSpreadAttribute = 262, + JsxExpression = 263, + CaseClause = 264, + DefaultClause = 265, + HeritageClause = 266, + CatchClause = 267, + PropertyAssignment = 268, + ShorthandPropertyAssignment = 269, + SpreadAssignment = 270, + EnumMember = 271, + SourceFile = 272, + Bundle = 273, + JSDocTypeExpression = 274, + JSDocAllType = 275, + JSDocUnknownType = 276, + JSDocNullableType = 277, + JSDocNonNullableType = 278, + JSDocOptionalType = 279, + JSDocFunctionType = 280, + JSDocVariadicType = 281, + JSDocComment = 282, + JSDocTypeLiteral = 283, + JSDocTag = 284, + JSDocAugmentsTag = 285, + JSDocClassTag = 286, + JSDocParameterTag = 287, + JSDocReturnTag = 288, + JSDocTypeTag = 289, + JSDocTemplateTag = 290, + JSDocTypedefTag = 291, + JSDocPropertyTag = 292, + SyntaxList = 293, + NotEmittedStatement = 294, + PartiallyEmittedExpression = 295, + CommaListExpression = 296, + MergeDeclarationMarker = 297, + EndOfDeclarationMarker = 298, + Count = 299, FirstAssignment = 58, LastAssignment = 70, FirstCompoundAssignment = 59, @@ -366,15 +368,15 @@ declare namespace ts { FirstReservedWord = 72, LastReservedWord = 107, FirstKeyword = 72, - LastKeyword = 143, + LastKeyword = 144, FirstFutureReservedWord = 108, LastFutureReservedWord = 116, - FirstTypeNode = 159, - LastTypeNode = 175, + FirstTypeNode = 160, + LastTypeNode = 177, FirstPunctuation = 17, LastPunctuation = 70, FirstToken = 0, - LastToken = 143, + LastToken = 144, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -383,11 +385,11 @@ declare namespace ts { LastTemplateToken = 16, FirstBinaryOperator = 27, LastBinaryOperator = 70, - FirstNode = 144, - FirstJSDocNode = 272, - LastJSDocNode = 290, - FirstJSDocTagNode = 282, - LastJSDocTagNode = 290, + FirstNode = 145, + FirstJSDocNode = 274, + LastJSDocNode = 292, + FirstJSDocTagNode = 284, + LastJSDocTagNode = 292, } enum NodeFlags { None = 0, @@ -518,7 +520,7 @@ declare namespace ts { } interface TypeParameterDeclaration extends NamedDeclaration { kind: SyntaxKind.TypeParameter; - parent?: DeclarationWithTypeParameters; + parent?: DeclarationWithTypeParameters | InferTypeNode; name: Identifier; constraint?: TypeNode; default?: TypeNode; @@ -742,6 +744,10 @@ declare namespace ts { trueType: TypeNode; falseType: TypeNode; } + interface InferTypeNode extends TypeNode { + kind: SyntaxKind.InferType; + typeParameter: TypeParameterDeclaration; + } interface ParenthesizedTypeNode extends TypeNode { kind: SyntaxKind.ParenthesizedType; type: TypeNode; @@ -2205,6 +2211,8 @@ declare namespace ts { NakedTypeVariable = 1, MappedType = 2, ReturnType = 4, + NoConstraints = 8, + AlwaysStrict = 16, } interface InferenceInfo { typeParameter: TypeParameter; @@ -3073,6 +3081,7 @@ declare namespace ts { function isUnionTypeNode(node: Node): node is UnionTypeNode; function isIntersectionTypeNode(node: Node): node is IntersectionTypeNode; function isConditionalTypeNode(node: Node): node is ConditionalTypeNode; + function isInferTypeNode(node: Node): node is InferTypeNode; function isParenthesizedTypeNode(node: Node): node is ParenthesizedTypeNode; function isThisTypeNode(node: Node): node is ThisTypeNode; function isTypeOperatorNode(node: Node): node is TypeOperatorNode; @@ -3494,6 +3503,8 @@ declare namespace ts { function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: ReadonlyArray): UnionOrIntersectionTypeNode; function createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; 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 createParenthesizedType(type: TypeNode): ParenthesizedTypeNode; function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode; function createThisTypeNode(): ThisTypeNode; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index a41e25a5da1..65fcacaa5aa 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -187,178 +187,180 @@ declare namespace ts { ConstructorKeyword = 123, DeclareKeyword = 124, GetKeyword = 125, - IsKeyword = 126, - KeyOfKeyword = 127, - ModuleKeyword = 128, - NamespaceKeyword = 129, - NeverKeyword = 130, - ReadonlyKeyword = 131, - RequireKeyword = 132, - NumberKeyword = 133, - ObjectKeyword = 134, - SetKeyword = 135, - StringKeyword = 136, - SymbolKeyword = 137, - TypeKeyword = 138, - UndefinedKeyword = 139, - UniqueKeyword = 140, - FromKeyword = 141, - GlobalKeyword = 142, - OfKeyword = 143, - QualifiedName = 144, - ComputedPropertyName = 145, - TypeParameter = 146, - Parameter = 147, - Decorator = 148, - PropertySignature = 149, - PropertyDeclaration = 150, - MethodSignature = 151, - MethodDeclaration = 152, - Constructor = 153, - GetAccessor = 154, - SetAccessor = 155, - CallSignature = 156, - ConstructSignature = 157, - IndexSignature = 158, - TypePredicate = 159, - TypeReference = 160, - FunctionType = 161, - ConstructorType = 162, - TypeQuery = 163, - TypeLiteral = 164, - ArrayType = 165, - TupleType = 166, - UnionType = 167, - IntersectionType = 168, - ConditionalType = 169, - ParenthesizedType = 170, - ThisType = 171, - TypeOperator = 172, - IndexedAccessType = 173, - MappedType = 174, - LiteralType = 175, - ObjectBindingPattern = 176, - ArrayBindingPattern = 177, - BindingElement = 178, - ArrayLiteralExpression = 179, - ObjectLiteralExpression = 180, - PropertyAccessExpression = 181, - ElementAccessExpression = 182, - CallExpression = 183, - NewExpression = 184, - TaggedTemplateExpression = 185, - TypeAssertionExpression = 186, - ParenthesizedExpression = 187, - FunctionExpression = 188, - ArrowFunction = 189, - DeleteExpression = 190, - TypeOfExpression = 191, - VoidExpression = 192, - AwaitExpression = 193, - PrefixUnaryExpression = 194, - PostfixUnaryExpression = 195, - BinaryExpression = 196, - ConditionalExpression = 197, - TemplateExpression = 198, - YieldExpression = 199, - SpreadElement = 200, - ClassExpression = 201, - OmittedExpression = 202, - ExpressionWithTypeArguments = 203, - AsExpression = 204, - NonNullExpression = 205, - MetaProperty = 206, - TemplateSpan = 207, - SemicolonClassElement = 208, - Block = 209, - VariableStatement = 210, - EmptyStatement = 211, - ExpressionStatement = 212, - IfStatement = 213, - DoStatement = 214, - WhileStatement = 215, - ForStatement = 216, - ForInStatement = 217, - ForOfStatement = 218, - ContinueStatement = 219, - BreakStatement = 220, - ReturnStatement = 221, - WithStatement = 222, - SwitchStatement = 223, - LabeledStatement = 224, - ThrowStatement = 225, - TryStatement = 226, - DebuggerStatement = 227, - VariableDeclaration = 228, - VariableDeclarationList = 229, - FunctionDeclaration = 230, - ClassDeclaration = 231, - InterfaceDeclaration = 232, - TypeAliasDeclaration = 233, - EnumDeclaration = 234, - ModuleDeclaration = 235, - ModuleBlock = 236, - CaseBlock = 237, - NamespaceExportDeclaration = 238, - ImportEqualsDeclaration = 239, - ImportDeclaration = 240, - ImportClause = 241, - NamespaceImport = 242, - NamedImports = 243, - ImportSpecifier = 244, - ExportAssignment = 245, - ExportDeclaration = 246, - NamedExports = 247, - ExportSpecifier = 248, - MissingDeclaration = 249, - ExternalModuleReference = 250, - JsxElement = 251, - JsxSelfClosingElement = 252, - JsxOpeningElement = 253, - JsxClosingElement = 254, - JsxFragment = 255, - JsxOpeningFragment = 256, - JsxClosingFragment = 257, - JsxAttribute = 258, - JsxAttributes = 259, - JsxSpreadAttribute = 260, - JsxExpression = 261, - CaseClause = 262, - DefaultClause = 263, - HeritageClause = 264, - CatchClause = 265, - PropertyAssignment = 266, - ShorthandPropertyAssignment = 267, - SpreadAssignment = 268, - EnumMember = 269, - SourceFile = 270, - Bundle = 271, - JSDocTypeExpression = 272, - JSDocAllType = 273, - JSDocUnknownType = 274, - JSDocNullableType = 275, - JSDocNonNullableType = 276, - JSDocOptionalType = 277, - JSDocFunctionType = 278, - JSDocVariadicType = 279, - JSDocComment = 280, - JSDocTypeLiteral = 281, - JSDocTag = 282, - JSDocAugmentsTag = 283, - JSDocClassTag = 284, - JSDocParameterTag = 285, - JSDocReturnTag = 286, - JSDocTypeTag = 287, - JSDocTemplateTag = 288, - JSDocTypedefTag = 289, - JSDocPropertyTag = 290, - SyntaxList = 291, - NotEmittedStatement = 292, - PartiallyEmittedExpression = 293, - CommaListExpression = 294, - MergeDeclarationMarker = 295, - EndOfDeclarationMarker = 296, - Count = 297, + InferKeyword = 126, + IsKeyword = 127, + KeyOfKeyword = 128, + ModuleKeyword = 129, + NamespaceKeyword = 130, + NeverKeyword = 131, + ReadonlyKeyword = 132, + RequireKeyword = 133, + NumberKeyword = 134, + ObjectKeyword = 135, + SetKeyword = 136, + StringKeyword = 137, + SymbolKeyword = 138, + TypeKeyword = 139, + UndefinedKeyword = 140, + UniqueKeyword = 141, + FromKeyword = 142, + GlobalKeyword = 143, + OfKeyword = 144, + QualifiedName = 145, + ComputedPropertyName = 146, + TypeParameter = 147, + Parameter = 148, + Decorator = 149, + PropertySignature = 150, + PropertyDeclaration = 151, + MethodSignature = 152, + MethodDeclaration = 153, + Constructor = 154, + GetAccessor = 155, + 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, + ObjectBindingPattern = 178, + ArrayBindingPattern = 179, + BindingElement = 180, + ArrayLiteralExpression = 181, + ObjectLiteralExpression = 182, + PropertyAccessExpression = 183, + ElementAccessExpression = 184, + CallExpression = 185, + NewExpression = 186, + TaggedTemplateExpression = 187, + TypeAssertionExpression = 188, + ParenthesizedExpression = 189, + FunctionExpression = 190, + ArrowFunction = 191, + DeleteExpression = 192, + TypeOfExpression = 193, + VoidExpression = 194, + AwaitExpression = 195, + PrefixUnaryExpression = 196, + PostfixUnaryExpression = 197, + BinaryExpression = 198, + ConditionalExpression = 199, + TemplateExpression = 200, + YieldExpression = 201, + SpreadElement = 202, + ClassExpression = 203, + OmittedExpression = 204, + ExpressionWithTypeArguments = 205, + AsExpression = 206, + NonNullExpression = 207, + MetaProperty = 208, + TemplateSpan = 209, + SemicolonClassElement = 210, + Block = 211, + VariableStatement = 212, + EmptyStatement = 213, + ExpressionStatement = 214, + IfStatement = 215, + DoStatement = 216, + WhileStatement = 217, + ForStatement = 218, + ForInStatement = 219, + ForOfStatement = 220, + ContinueStatement = 221, + BreakStatement = 222, + ReturnStatement = 223, + WithStatement = 224, + SwitchStatement = 225, + LabeledStatement = 226, + ThrowStatement = 227, + TryStatement = 228, + DebuggerStatement = 229, + VariableDeclaration = 230, + VariableDeclarationList = 231, + FunctionDeclaration = 232, + ClassDeclaration = 233, + InterfaceDeclaration = 234, + TypeAliasDeclaration = 235, + EnumDeclaration = 236, + ModuleDeclaration = 237, + ModuleBlock = 238, + CaseBlock = 239, + NamespaceExportDeclaration = 240, + ImportEqualsDeclaration = 241, + ImportDeclaration = 242, + ImportClause = 243, + NamespaceImport = 244, + NamedImports = 245, + ImportSpecifier = 246, + ExportAssignment = 247, + ExportDeclaration = 248, + NamedExports = 249, + ExportSpecifier = 250, + MissingDeclaration = 251, + ExternalModuleReference = 252, + JsxElement = 253, + JsxSelfClosingElement = 254, + JsxOpeningElement = 255, + JsxClosingElement = 256, + JsxFragment = 257, + JsxOpeningFragment = 258, + JsxClosingFragment = 259, + JsxAttribute = 260, + JsxAttributes = 261, + JsxSpreadAttribute = 262, + JsxExpression = 263, + CaseClause = 264, + DefaultClause = 265, + HeritageClause = 266, + CatchClause = 267, + PropertyAssignment = 268, + ShorthandPropertyAssignment = 269, + SpreadAssignment = 270, + EnumMember = 271, + SourceFile = 272, + Bundle = 273, + JSDocTypeExpression = 274, + JSDocAllType = 275, + JSDocUnknownType = 276, + JSDocNullableType = 277, + JSDocNonNullableType = 278, + JSDocOptionalType = 279, + JSDocFunctionType = 280, + JSDocVariadicType = 281, + JSDocComment = 282, + JSDocTypeLiteral = 283, + JSDocTag = 284, + JSDocAugmentsTag = 285, + JSDocClassTag = 286, + JSDocParameterTag = 287, + JSDocReturnTag = 288, + JSDocTypeTag = 289, + JSDocTemplateTag = 290, + JSDocTypedefTag = 291, + JSDocPropertyTag = 292, + SyntaxList = 293, + NotEmittedStatement = 294, + PartiallyEmittedExpression = 295, + CommaListExpression = 296, + MergeDeclarationMarker = 297, + EndOfDeclarationMarker = 298, + Count = 299, FirstAssignment = 58, LastAssignment = 70, FirstCompoundAssignment = 59, @@ -366,15 +368,15 @@ declare namespace ts { FirstReservedWord = 72, LastReservedWord = 107, FirstKeyword = 72, - LastKeyword = 143, + LastKeyword = 144, FirstFutureReservedWord = 108, LastFutureReservedWord = 116, - FirstTypeNode = 159, - LastTypeNode = 175, + FirstTypeNode = 160, + LastTypeNode = 177, FirstPunctuation = 17, LastPunctuation = 70, FirstToken = 0, - LastToken = 143, + LastToken = 144, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -383,11 +385,11 @@ declare namespace ts { LastTemplateToken = 16, FirstBinaryOperator = 27, LastBinaryOperator = 70, - FirstNode = 144, - FirstJSDocNode = 272, - LastJSDocNode = 290, - FirstJSDocTagNode = 282, - LastJSDocTagNode = 290, + FirstNode = 145, + FirstJSDocNode = 274, + LastJSDocNode = 292, + FirstJSDocTagNode = 284, + LastJSDocTagNode = 292, } enum NodeFlags { None = 0, @@ -518,7 +520,7 @@ declare namespace ts { } interface TypeParameterDeclaration extends NamedDeclaration { kind: SyntaxKind.TypeParameter; - parent?: DeclarationWithTypeParameters; + parent?: DeclarationWithTypeParameters | InferTypeNode; name: Identifier; constraint?: TypeNode; default?: TypeNode; @@ -742,6 +744,10 @@ declare namespace ts { trueType: TypeNode; falseType: TypeNode; } + interface InferTypeNode extends TypeNode { + kind: SyntaxKind.InferType; + typeParameter: TypeParameterDeclaration; + } interface ParenthesizedTypeNode extends TypeNode { kind: SyntaxKind.ParenthesizedType; type: TypeNode; @@ -2205,6 +2211,8 @@ declare namespace ts { NakedTypeVariable = 1, MappedType = 2, ReturnType = 4, + NoConstraints = 8, + AlwaysStrict = 16, } interface InferenceInfo { typeParameter: TypeParameter; @@ -3128,6 +3136,7 @@ declare namespace ts { function isUnionTypeNode(node: Node): node is UnionTypeNode; function isIntersectionTypeNode(node: Node): node is IntersectionTypeNode; function isConditionalTypeNode(node: Node): node is ConditionalTypeNode; + function isInferTypeNode(node: Node): node is InferTypeNode; function isParenthesizedTypeNode(node: Node): node is ParenthesizedTypeNode; function isThisTypeNode(node: Node): node is ThisTypeNode; function isTypeOperatorNode(node: Node): node is TypeOperatorNode; @@ -3441,6 +3450,8 @@ declare namespace ts { function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: ReadonlyArray): UnionOrIntersectionTypeNode; function createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode; 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 createParenthesizedType(type: TypeNode): ParenthesizedTypeNode; function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode; function createThisTypeNode(): ThisTypeNode; diff --git a/tests/baselines/reference/conditionalTypes1.errors.txt b/tests/baselines/reference/conditionalTypes1.errors.txt index 900925052ac..8016c4449d3 100644 --- a/tests/baselines/reference/conditionalTypes1.errors.txt +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -334,4 +334,8 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(157,5): error TS2 type O7 = Or; // true type O8 = Or; // true type O9 = Or; // boolean + + type T40 = never extends never ? true : false; // true + type T41 = number extends never ? true : false; // false + type T42 = never extends number ? true : false; // boolean \ No newline at end of file diff --git a/tests/baselines/reference/conditionalTypes1.js b/tests/baselines/reference/conditionalTypes1.js index 54241bb553a..088181b3b12 100644 --- a/tests/baselines/reference/conditionalTypes1.js +++ b/tests/baselines/reference/conditionalTypes1.js @@ -194,6 +194,10 @@ type O6 = Or; // boolean type O7 = Or; // true type O8 = Or; // true type O9 = Or; // boolean + +type T40 = never extends never ? true : false; // true +type T41 = number extends never ? true : false; // false +type T42 = never extends number ? true : false; // boolean //// [conditionalTypes1.js] @@ -398,3 +402,6 @@ declare type O6 = Or; declare type O7 = Or; declare type O8 = Or; declare type O9 = Or; +declare type T40 = never extends never ? true : false; +declare type T41 = number extends never ? true : false; +declare type T42 = never extends number ? true : false; diff --git a/tests/baselines/reference/conditionalTypes1.symbols b/tests/baselines/reference/conditionalTypes1.symbols index 16322f4c151..ab0426f67d5 100644 --- a/tests/baselines/reference/conditionalTypes1.symbols +++ b/tests/baselines/reference/conditionalTypes1.symbols @@ -751,3 +751,12 @@ type O9 = Or; // boolean >O9 : Symbol(O9, Decl(conditionalTypes1.ts, 193, 28)) >Or : Symbol(Or, Decl(conditionalTypes1.ts, 162, 65)) +type T40 = never extends never ? true : false; // true +>T40 : Symbol(T40, Decl(conditionalTypes1.ts, 194, 31)) + +type T41 = number extends never ? true : false; // false +>T41 : Symbol(T41, Decl(conditionalTypes1.ts, 196, 46)) + +type T42 = never extends number ? true : false; // boolean +>T42 : Symbol(T42, Decl(conditionalTypes1.ts, 197, 47)) + diff --git a/tests/baselines/reference/conditionalTypes1.types b/tests/baselines/reference/conditionalTypes1.types index 86a02fa001b..9fc72f368d5 100644 --- a/tests/baselines/reference/conditionalTypes1.types +++ b/tests/baselines/reference/conditionalTypes1.types @@ -849,3 +849,18 @@ type O9 = Or; // boolean >O9 : boolean >Or : If +type T40 = never extends never ? true : false; // true +>T40 : true +>true : true +>false : false + +type T41 = number extends never ? true : false; // false +>T41 : false +>true : true +>false : false + +type T42 = never extends number ? true : false; // boolean +>T42 : boolean +>true : true +>false : false + diff --git a/tests/baselines/reference/inferTypes1.errors.txt b/tests/baselines/reference/inferTypes1.errors.txt new file mode 100644 index 00000000000..79a0e430cbd --- /dev/null +++ b/tests/baselines/reference/inferTypes1.errors.txt @@ -0,0 +1,111 @@ +tests/cases/conformance/types/conditional/inferTypes1.ts(34,23): error TS2344: Type 'string' does not satisfy the constraint 'Function'. +tests/cases/conformance/types/conditional/inferTypes1.ts(43,25): error TS2344: Type '(x: string, y: string) => number' does not satisfy the constraint '(x: any) => any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(44,25): error TS2344: Type 'Function' does not satisfy the constraint '(x: any) => any'. + Type 'Function' provides no match for the signature '(x: any): any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(70,12): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. +tests/cases/conformance/types/conditional/inferTypes1.ts(71,15): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. +tests/cases/conformance/types/conditional/inferTypes1.ts(71,41): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. +tests/cases/conformance/types/conditional/inferTypes1.ts(71,51): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. +tests/cases/conformance/types/conditional/inferTypes1.ts(72,15): error TS2304: Cannot find name 'U'. +tests/cases/conformance/types/conditional/inferTypes1.ts(72,15): error TS4081: Exported type alias 'T62' has or is using private name 'U'. +tests/cases/conformance/types/conditional/inferTypes1.ts(72,43): error TS2304: Cannot find name 'U'. +tests/cases/conformance/types/conditional/inferTypes1.ts(72,43): error TS4081: Exported type alias 'T62' has or is using private name 'U'. + + +==== tests/cases/conformance/types/conditional/inferTypes1.ts (11 errors) ==== + type Unpacked = + T extends (infer U)[] ? U : + T extends (...args: any[]) => infer U ? U : + T extends Promise ? U : + T; + + type T00 = Unpacked; // string + type T01 = Unpacked; // string + type T02 = Unpacked<() => string>; // string + type T03 = Unpacked>; // string + type T04 = Unpacked[]>>; // string + type T05 = Unpacked; // any + type T06 = Unpacked; // never + + type ReturnType = T extends ((...args: any[]) => infer R) | (new (...args: any[]) => infer R) ? R : any; + + function f1(s: string) { + return { a: 1, b: s }; + } + + class C { + x = 0; + y = 0; + } + + type T10 = ReturnType<() => string>; // string + type T11 = ReturnType<(s: string) => void>; // void + type T12 = ReturnType<(() => T)>; // {} + type T13 = ReturnType<(() => T)>; // number[] + type T14 = ReturnType; // { a: number, b: string } + type T15 = ReturnType; // C + type T16 = ReturnType; // any + type T17 = ReturnType; // any + type T18 = ReturnType; // Error + ~~~~~~ +!!! error TS2344: Type 'string' does not satisfy the constraint 'Function'. + type T19 = ReturnType; // any + + type ArgumentType any> = T extends (a: infer A) => any ? A : any; + + type T20 = ArgumentType<() => void>; // never + type T21 = ArgumentType<(x: string) => number>; // string + type T22 = ArgumentType<(x?: string) => number>; // string | undefined + type T23 = ArgumentType<(...args: string[]) => number>; // string + type T24 = ArgumentType<(x: string, y: string) => number>; // Error + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2344: Type '(x: string, y: string) => number' does not satisfy the constraint '(x: any) => any'. + type T25 = ArgumentType; // Error + ~~~~~~~~ +!!! error TS2344: Type 'Function' does not satisfy the constraint '(x: any) => any'. +!!! error TS2344: Type 'Function' provides no match for the signature '(x: any): any'. + type T26 = ArgumentType; // any + type T27 = ArgumentType; // any + + type X1 = T extends { x: infer X, y: infer Y } ? [X, Y] : any; + + type T30 = X1<{ x: any, y: any }>; // [any, any] + type T31 = X1<{ x: number, y: string }>; // [number, string] + type T32 = X1<{ x: number, y: string, z: boolean }>; // [number, string] + + type X2 = T extends { a: infer U, b: infer U } ? U : never; + + type T40 = X2<{}>; // never + type T41 = X2<{ a: string }>; // never + type T42 = X2<{ a: string, b: string }>; // string + type T43 = X2<{ a: number, b: string }>; // string | number + type T44 = X2<{ a: number, b: string, c: boolean }>; // string | number + + type X3 = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never; + + type T50 = X3<{}>; // never + type T51 = X3<{ a: (x: string) => void }>; // never + type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string + type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number + type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number + + type T60 = infer U; // Error + ~~~~~~~ +!!! error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. + type T61 = infer A extends infer B ? infer C : infer D; // Error + ~~~~~~~ +!!! error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. + ~~~~~~~ +!!! error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. + ~~~~~~~ +!!! error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. + type T62 = U extends (infer U)[] ? U : U; // Error + ~ +!!! error TS2304: Cannot find name 'U'. + ~ +!!! error TS4081: Exported type alias 'T62' has or is using private name 'U'. + ~ +!!! error TS2304: Cannot find name 'U'. + ~ +!!! error TS4081: Exported type alias 'T62' has or is using private name 'U'. + \ No newline at end of file diff --git a/tests/baselines/reference/inferTypes1.js b/tests/baselines/reference/inferTypes1.js new file mode 100644 index 00000000000..231c39e8952 --- /dev/null +++ b/tests/baselines/reference/inferTypes1.js @@ -0,0 +1,87 @@ +//// [inferTypes1.ts] +type Unpacked = + T extends (infer U)[] ? U : + T extends (...args: any[]) => infer U ? U : + T extends Promise ? U : + T; + +type T00 = Unpacked; // string +type T01 = Unpacked; // string +type T02 = Unpacked<() => string>; // string +type T03 = Unpacked>; // string +type T04 = Unpacked[]>>; // string +type T05 = Unpacked; // any +type T06 = Unpacked; // never + +type ReturnType = T extends ((...args: any[]) => infer R) | (new (...args: any[]) => infer R) ? R : any; + +function f1(s: string) { + return { a: 1, b: s }; +} + +class C { + x = 0; + y = 0; +} + +type T10 = ReturnType<() => string>; // string +type T11 = ReturnType<(s: string) => void>; // void +type T12 = ReturnType<(() => T)>; // {} +type T13 = ReturnType<(() => T)>; // number[] +type T14 = ReturnType; // { a: number, b: string } +type T15 = ReturnType; // C +type T16 = ReturnType; // any +type T17 = ReturnType; // any +type T18 = ReturnType; // Error +type T19 = ReturnType; // any + +type ArgumentType any> = T extends (a: infer A) => any ? A : any; + +type T20 = ArgumentType<() => void>; // never +type T21 = ArgumentType<(x: string) => number>; // string +type T22 = ArgumentType<(x?: string) => number>; // string | undefined +type T23 = ArgumentType<(...args: string[]) => number>; // string +type T24 = ArgumentType<(x: string, y: string) => number>; // Error +type T25 = ArgumentType; // Error +type T26 = ArgumentType; // any +type T27 = ArgumentType; // any + +type X1 = T extends { x: infer X, y: infer Y } ? [X, Y] : any; + +type T30 = X1<{ x: any, y: any }>; // [any, any] +type T31 = X1<{ x: number, y: string }>; // [number, string] +type T32 = X1<{ x: number, y: string, z: boolean }>; // [number, string] + +type X2 = T extends { a: infer U, b: infer U } ? U : never; + +type T40 = X2<{}>; // never +type T41 = X2<{ a: string }>; // never +type T42 = X2<{ a: string, b: string }>; // string +type T43 = X2<{ a: number, b: string }>; // string | number +type T44 = X2<{ a: number, b: string, c: boolean }>; // string | number + +type X3 = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never; + +type T50 = X3<{}>; // never +type T51 = X3<{ a: (x: string) => void }>; // never +type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string +type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number +type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number + +type T60 = infer U; // Error +type T61 = infer A extends infer B ? infer C : infer D; // Error +type T62 = U extends (infer U)[] ? U : U; // Error + + +//// [inferTypes1.js] +"use strict"; +function f1(s) { + return { a: 1, b: s }; +} +var C = /** @class */ (function () { + function C() { + this.x = 0; + this.y = 0; + } + return C; +}()); diff --git a/tests/baselines/reference/inferTypes1.symbols b/tests/baselines/reference/inferTypes1.symbols new file mode 100644 index 00000000000..a85f124dede --- /dev/null +++ b/tests/baselines/reference/inferTypes1.symbols @@ -0,0 +1,317 @@ +=== tests/cases/conformance/types/conditional/inferTypes1.ts === +type Unpacked = +>Unpacked : Symbol(Unpacked, Decl(inferTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(inferTypes1.ts, 0, 14)) + + T extends (infer U)[] ? U : +>T : Symbol(T, Decl(inferTypes1.ts, 0, 14)) +>U : Symbol(U, Decl(inferTypes1.ts, 1, 20)) +>U : Symbol(U, Decl(inferTypes1.ts, 1, 20)) + + T extends (...args: any[]) => infer U ? U : +>T : Symbol(T, Decl(inferTypes1.ts, 0, 14)) +>args : Symbol(args, Decl(inferTypes1.ts, 2, 15)) +>U : Symbol(U, Decl(inferTypes1.ts, 2, 39)) +>U : Symbol(U, Decl(inferTypes1.ts, 2, 39)) + + T extends Promise ? U : +>T : Symbol(T, Decl(inferTypes1.ts, 0, 14)) +>Promise : Symbol(Promise, Decl(lib.d.ts, --, --)) +>U : Symbol(U, Decl(inferTypes1.ts, 3, 27)) +>U : Symbol(U, Decl(inferTypes1.ts, 3, 27)) + + T; +>T : Symbol(T, Decl(inferTypes1.ts, 0, 14)) + +type T00 = Unpacked; // string +>T00 : Symbol(T00, Decl(inferTypes1.ts, 4, 6)) +>Unpacked : Symbol(Unpacked, Decl(inferTypes1.ts, 0, 0)) + +type T01 = Unpacked; // string +>T01 : Symbol(T01, Decl(inferTypes1.ts, 6, 28)) +>Unpacked : Symbol(Unpacked, Decl(inferTypes1.ts, 0, 0)) + +type T02 = Unpacked<() => string>; // string +>T02 : Symbol(T02, Decl(inferTypes1.ts, 7, 30)) +>Unpacked : Symbol(Unpacked, Decl(inferTypes1.ts, 0, 0)) + +type T03 = Unpacked>; // string +>T03 : Symbol(T03, Decl(inferTypes1.ts, 8, 34)) +>Unpacked : Symbol(Unpacked, Decl(inferTypes1.ts, 0, 0)) +>Promise : Symbol(Promise, Decl(lib.d.ts, --, --)) + +type T04 = Unpacked[]>>; // string +>T04 : Symbol(T04, Decl(inferTypes1.ts, 9, 37)) +>Unpacked : Symbol(Unpacked, Decl(inferTypes1.ts, 0, 0)) +>Unpacked : Symbol(Unpacked, Decl(inferTypes1.ts, 0, 0)) +>Promise : Symbol(Promise, Decl(lib.d.ts, --, --)) + +type T05 = Unpacked; // any +>T05 : Symbol(T05, Decl(inferTypes1.ts, 10, 49)) +>Unpacked : Symbol(Unpacked, Decl(inferTypes1.ts, 0, 0)) + +type T06 = Unpacked; // never +>T06 : Symbol(T06, Decl(inferTypes1.ts, 11, 25)) +>Unpacked : Symbol(Unpacked, Decl(inferTypes1.ts, 0, 0)) + +type ReturnType = T extends ((...args: any[]) => infer R) | (new (...args: any[]) => infer R) ? R : any; +>ReturnType : Symbol(ReturnType, Decl(inferTypes1.ts, 12, 27)) +>T : Symbol(T, Decl(inferTypes1.ts, 14, 16)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(inferTypes1.ts, 14, 16)) +>args : Symbol(args, Decl(inferTypes1.ts, 14, 50)) +>R : Symbol(R, Decl(inferTypes1.ts, 14, 74), Decl(inferTypes1.ts, 14, 110)) +>args : Symbol(args, Decl(inferTypes1.ts, 14, 86)) +>R : Symbol(R, Decl(inferTypes1.ts, 14, 74), Decl(inferTypes1.ts, 14, 110)) +>R : Symbol(R, Decl(inferTypes1.ts, 14, 74), Decl(inferTypes1.ts, 14, 110)) + +function f1(s: string) { +>f1 : Symbol(f1, Decl(inferTypes1.ts, 14, 124)) +>s : Symbol(s, Decl(inferTypes1.ts, 16, 12)) + + return { a: 1, b: s }; +>a : Symbol(a, Decl(inferTypes1.ts, 17, 12)) +>b : Symbol(b, Decl(inferTypes1.ts, 17, 18)) +>s : Symbol(s, Decl(inferTypes1.ts, 16, 12)) +} + +class C { +>C : Symbol(C, Decl(inferTypes1.ts, 18, 1)) + + x = 0; +>x : Symbol(C.x, Decl(inferTypes1.ts, 20, 9)) + + y = 0; +>y : Symbol(C.y, Decl(inferTypes1.ts, 21, 10)) +} + +type T10 = ReturnType<() => string>; // string +>T10 : Symbol(T10, Decl(inferTypes1.ts, 23, 1)) +>ReturnType : Symbol(ReturnType, Decl(inferTypes1.ts, 12, 27)) + +type T11 = ReturnType<(s: string) => void>; // void +>T11 : Symbol(T11, Decl(inferTypes1.ts, 25, 36)) +>ReturnType : Symbol(ReturnType, Decl(inferTypes1.ts, 12, 27)) +>s : Symbol(s, Decl(inferTypes1.ts, 26, 23)) + +type T12 = ReturnType<(() => T)>; // {} +>T12 : Symbol(T12, Decl(inferTypes1.ts, 26, 43)) +>ReturnType : Symbol(ReturnType, Decl(inferTypes1.ts, 12, 27)) +>T : Symbol(T, Decl(inferTypes1.ts, 27, 24)) +>T : Symbol(T, Decl(inferTypes1.ts, 27, 24)) + +type T13 = ReturnType<(() => T)>; // number[] +>T13 : Symbol(T13, Decl(inferTypes1.ts, 27, 36)) +>ReturnType : Symbol(ReturnType, Decl(inferTypes1.ts, 12, 27)) +>T : Symbol(T, Decl(inferTypes1.ts, 28, 24)) +>U : Symbol(U, Decl(inferTypes1.ts, 28, 36)) +>U : Symbol(U, Decl(inferTypes1.ts, 28, 36)) +>T : Symbol(T, Decl(inferTypes1.ts, 28, 24)) + +type T14 = ReturnType; // { a: number, b: string } +>T14 : Symbol(T14, Decl(inferTypes1.ts, 28, 66)) +>ReturnType : Symbol(ReturnType, Decl(inferTypes1.ts, 12, 27)) +>f1 : Symbol(f1, Decl(inferTypes1.ts, 14, 124)) + +type T15 = ReturnType; // C +>T15 : Symbol(T15, Decl(inferTypes1.ts, 29, 33)) +>ReturnType : Symbol(ReturnType, Decl(inferTypes1.ts, 12, 27)) +>C : Symbol(C, Decl(inferTypes1.ts, 18, 1)) + +type T16 = ReturnType; // any +>T16 : Symbol(T16, Decl(inferTypes1.ts, 30, 32)) +>ReturnType : Symbol(ReturnType, Decl(inferTypes1.ts, 12, 27)) + +type T17 = ReturnType; // any +>T17 : Symbol(T17, Decl(inferTypes1.ts, 31, 27)) +>ReturnType : Symbol(ReturnType, Decl(inferTypes1.ts, 12, 27)) + +type T18 = ReturnType; // Error +>T18 : Symbol(T18, Decl(inferTypes1.ts, 32, 29)) +>ReturnType : Symbol(ReturnType, Decl(inferTypes1.ts, 12, 27)) + +type T19 = ReturnType; // any +>T19 : Symbol(T19, Decl(inferTypes1.ts, 33, 30)) +>ReturnType : Symbol(ReturnType, Decl(inferTypes1.ts, 12, 27)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +type ArgumentType any> = T extends (a: infer A) => any ? A : any; +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 34, 32)) +>T : Symbol(T, Decl(inferTypes1.ts, 36, 18)) +>x : Symbol(x, Decl(inferTypes1.ts, 36, 29)) +>T : Symbol(T, Decl(inferTypes1.ts, 36, 18)) +>a : Symbol(a, Decl(inferTypes1.ts, 36, 58)) +>A : Symbol(A, Decl(inferTypes1.ts, 36, 66)) +>A : Symbol(A, Decl(inferTypes1.ts, 36, 66)) + +type T20 = ArgumentType<() => void>; // never +>T20 : Symbol(T20, Decl(inferTypes1.ts, 36, 87)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 34, 32)) + +type T21 = ArgumentType<(x: string) => number>; // string +>T21 : Symbol(T21, Decl(inferTypes1.ts, 38, 36)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 34, 32)) +>x : Symbol(x, Decl(inferTypes1.ts, 39, 25)) + +type T22 = ArgumentType<(x?: string) => number>; // string | undefined +>T22 : Symbol(T22, Decl(inferTypes1.ts, 39, 47)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 34, 32)) +>x : Symbol(x, Decl(inferTypes1.ts, 40, 25)) + +type T23 = ArgumentType<(...args: string[]) => number>; // string +>T23 : Symbol(T23, Decl(inferTypes1.ts, 40, 48)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 34, 32)) +>args : Symbol(args, Decl(inferTypes1.ts, 41, 25)) + +type T24 = ArgumentType<(x: string, y: string) => number>; // Error +>T24 : Symbol(T24, Decl(inferTypes1.ts, 41, 55)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 34, 32)) +>x : Symbol(x, Decl(inferTypes1.ts, 42, 25)) +>y : Symbol(y, Decl(inferTypes1.ts, 42, 35)) + +type T25 = ArgumentType; // Error +>T25 : Symbol(T25, Decl(inferTypes1.ts, 42, 58)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 34, 32)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +type T26 = ArgumentType; // any +>T26 : Symbol(T26, Decl(inferTypes1.ts, 43, 34)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 34, 32)) + +type T27 = ArgumentType; // any +>T27 : Symbol(T27, Decl(inferTypes1.ts, 44, 29)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 34, 32)) + +type X1 = T extends { x: infer X, y: infer Y } ? [X, Y] : any; +>X1 : Symbol(X1, Decl(inferTypes1.ts, 45, 31)) +>T : Symbol(T, Decl(inferTypes1.ts, 47, 8)) +>x : Symbol(x, Decl(inferTypes1.ts, 47, 19)) +>y : Symbol(y, Decl(inferTypes1.ts, 47, 27)) +>T : Symbol(T, Decl(inferTypes1.ts, 47, 8)) +>x : Symbol(x, Decl(inferTypes1.ts, 47, 51)) +>X : Symbol(X, Decl(inferTypes1.ts, 47, 60)) +>y : Symbol(y, Decl(inferTypes1.ts, 47, 63)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 47, 72)) +>X : Symbol(X, Decl(inferTypes1.ts, 47, 60)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 47, 72)) + +type T30 = X1<{ x: any, y: any }>; // [any, any] +>T30 : Symbol(T30, Decl(inferTypes1.ts, 47, 92)) +>X1 : Symbol(X1, Decl(inferTypes1.ts, 45, 31)) +>x : Symbol(x, Decl(inferTypes1.ts, 49, 15)) +>y : Symbol(y, Decl(inferTypes1.ts, 49, 23)) + +type T31 = X1<{ x: number, y: string }>; // [number, string] +>T31 : Symbol(T31, Decl(inferTypes1.ts, 49, 34)) +>X1 : Symbol(X1, Decl(inferTypes1.ts, 45, 31)) +>x : Symbol(x, Decl(inferTypes1.ts, 50, 15)) +>y : Symbol(y, Decl(inferTypes1.ts, 50, 26)) + +type T32 = X1<{ x: number, y: string, z: boolean }>; // [number, string] +>T32 : Symbol(T32, Decl(inferTypes1.ts, 50, 40)) +>X1 : Symbol(X1, Decl(inferTypes1.ts, 45, 31)) +>x : Symbol(x, Decl(inferTypes1.ts, 51, 15)) +>y : Symbol(y, Decl(inferTypes1.ts, 51, 26)) +>z : Symbol(z, Decl(inferTypes1.ts, 51, 37)) + +type X2 = T extends { a: infer U, b: infer U } ? U : never; +>X2 : Symbol(X2, Decl(inferTypes1.ts, 51, 52)) +>T : Symbol(T, Decl(inferTypes1.ts, 53, 8)) +>T : Symbol(T, Decl(inferTypes1.ts, 53, 8)) +>a : Symbol(a, Decl(inferTypes1.ts, 53, 24)) +>U : Symbol(U, Decl(inferTypes1.ts, 53, 33), Decl(inferTypes1.ts, 53, 45)) +>b : Symbol(b, Decl(inferTypes1.ts, 53, 36)) +>U : Symbol(U, Decl(inferTypes1.ts, 53, 33), Decl(inferTypes1.ts, 53, 45)) +>U : Symbol(U, Decl(inferTypes1.ts, 53, 33), Decl(inferTypes1.ts, 53, 45)) + +type T40 = X2<{}>; // never +>T40 : Symbol(T40, Decl(inferTypes1.ts, 53, 62)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 51, 52)) + +type T41 = X2<{ a: string }>; // never +>T41 : Symbol(T41, Decl(inferTypes1.ts, 55, 18)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 51, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 56, 15)) + +type T42 = X2<{ a: string, b: string }>; // string +>T42 : Symbol(T42, Decl(inferTypes1.ts, 56, 29)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 51, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 57, 15)) +>b : Symbol(b, Decl(inferTypes1.ts, 57, 26)) + +type T43 = X2<{ a: number, b: string }>; // string | number +>T43 : Symbol(T43, Decl(inferTypes1.ts, 57, 40)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 51, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 58, 15)) +>b : Symbol(b, Decl(inferTypes1.ts, 58, 26)) + +type T44 = X2<{ a: number, b: string, c: boolean }>; // string | number +>T44 : Symbol(T44, Decl(inferTypes1.ts, 58, 40)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 51, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 59, 15)) +>b : Symbol(b, Decl(inferTypes1.ts, 59, 26)) +>c : Symbol(c, Decl(inferTypes1.ts, 59, 37)) + +type X3 = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never; +>X3 : Symbol(X3, Decl(inferTypes1.ts, 59, 52)) +>T : Symbol(T, Decl(inferTypes1.ts, 61, 8)) +>T : Symbol(T, Decl(inferTypes1.ts, 61, 8)) +>a : Symbol(a, Decl(inferTypes1.ts, 61, 24)) +>x : Symbol(x, Decl(inferTypes1.ts, 61, 29)) +>U : Symbol(U, Decl(inferTypes1.ts, 61, 37), Decl(inferTypes1.ts, 61, 62)) +>b : Symbol(b, Decl(inferTypes1.ts, 61, 49)) +>x : Symbol(x, Decl(inferTypes1.ts, 61, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 61, 37), Decl(inferTypes1.ts, 61, 62)) +>U : Symbol(U, Decl(inferTypes1.ts, 61, 37), Decl(inferTypes1.ts, 61, 62)) + +type T50 = X3<{}>; // never +>T50 : Symbol(T50, Decl(inferTypes1.ts, 61, 88)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 59, 52)) + +type T51 = X3<{ a: (x: string) => void }>; // never +>T51 : Symbol(T51, Decl(inferTypes1.ts, 63, 18)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 59, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 64, 15)) +>x : Symbol(x, Decl(inferTypes1.ts, 64, 20)) + +type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string +>T52 : Symbol(T52, Decl(inferTypes1.ts, 64, 42)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 59, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 65, 15)) +>x : Symbol(x, Decl(inferTypes1.ts, 65, 20)) +>b : Symbol(b, Decl(inferTypes1.ts, 65, 39)) +>x : Symbol(x, Decl(inferTypes1.ts, 65, 44)) + +type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number +>T53 : Symbol(T53, Decl(inferTypes1.ts, 65, 66)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 59, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 66, 15)) +>x : Symbol(x, Decl(inferTypes1.ts, 66, 20)) +>b : Symbol(b, Decl(inferTypes1.ts, 66, 39)) +>x : Symbol(x, Decl(inferTypes1.ts, 66, 44)) + +type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number +>T54 : Symbol(T54, Decl(inferTypes1.ts, 66, 66)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 59, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 67, 15)) +>x : Symbol(x, Decl(inferTypes1.ts, 67, 20)) +>b : Symbol(b, Decl(inferTypes1.ts, 67, 39)) + +type T60 = infer U; // Error +>T60 : Symbol(T60, Decl(inferTypes1.ts, 67, 57)) +>U : Symbol(U, Decl(inferTypes1.ts, 69, 16)) + +type T61 = infer A extends infer B ? infer C : infer D; // Error +>T61 : Symbol(T61, Decl(inferTypes1.ts, 69, 19)) +>T : Symbol(T, Decl(inferTypes1.ts, 70, 9)) +>A : Symbol(A, Decl(inferTypes1.ts, 70, 19)) +>B : Symbol(B, Decl(inferTypes1.ts, 70, 35)) +>C : Symbol(C, Decl(inferTypes1.ts, 70, 45)) +>D : Symbol(D, Decl(inferTypes1.ts, 70, 55)) + +type T62 = U extends (infer U)[] ? U : U; // Error +>T62 : Symbol(T62, Decl(inferTypes1.ts, 70, 58)) +>T : Symbol(T, Decl(inferTypes1.ts, 71, 9)) +>U : Symbol(U, Decl(inferTypes1.ts, 71, 30)) +>U : Symbol(U, Decl(inferTypes1.ts, 71, 30)) + diff --git a/tests/baselines/reference/inferTypes1.types b/tests/baselines/reference/inferTypes1.types new file mode 100644 index 00000000000..be974f8661a --- /dev/null +++ b/tests/baselines/reference/inferTypes1.types @@ -0,0 +1,323 @@ +=== tests/cases/conformance/types/conditional/inferTypes1.ts === +type Unpacked = +>Unpacked : Unpacked +>T : T + + T extends (infer U)[] ? U : +>T : T +>U : U +>U : U + + T extends (...args: any[]) => infer U ? U : +>T : T +>args : any[] +>U : U +>U : U + + T extends Promise ? U : +>T : T +>Promise : Promise +>U : U +>U : U + + T; +>T : T + +type T00 = Unpacked; // string +>T00 : string +>Unpacked : Unpacked + +type T01 = Unpacked; // string +>T01 : string +>Unpacked : Unpacked + +type T02 = Unpacked<() => string>; // string +>T02 : string +>Unpacked : Unpacked + +type T03 = Unpacked>; // string +>T03 : string +>Unpacked : Unpacked +>Promise : Promise + +type T04 = Unpacked[]>>; // string +>T04 : string +>Unpacked : Unpacked +>Unpacked : Unpacked +>Promise : Promise + +type T05 = Unpacked; // any +>T05 : any +>Unpacked : Unpacked + +type T06 = Unpacked; // never +>T06 : never +>Unpacked : Unpacked + +type ReturnType = T extends ((...args: any[]) => infer R) | (new (...args: any[]) => infer R) ? R : any; +>ReturnType : ReturnType +>T : T +>Function : Function +>T : T +>args : any[] +>R : R +>args : any[] +>R : R +>R : R + +function f1(s: string) { +>f1 : (s: string) => { a: number; b: string; } +>s : string + + return { a: 1, b: s }; +>{ a: 1, b: s } : { a: number; b: string; } +>a : number +>1 : 1 +>b : string +>s : string +} + +class C { +>C : C + + x = 0; +>x : number +>0 : 0 + + y = 0; +>y : number +>0 : 0 +} + +type T10 = ReturnType<() => string>; // string +>T10 : string +>ReturnType : ReturnType + +type T11 = ReturnType<(s: string) => void>; // void +>T11 : void +>ReturnType : ReturnType +>s : string + +type T12 = ReturnType<(() => T)>; // {} +>T12 : {} +>ReturnType : ReturnType +>T : T +>T : T + +type T13 = ReturnType<(() => T)>; // number[] +>T13 : number[] +>ReturnType : ReturnType +>T : T +>U : U +>U : U +>T : T + +type T14 = ReturnType; // { a: number, b: string } +>T14 : { a: number; b: string; } +>ReturnType : ReturnType +>f1 : (s: string) => { a: number; b: string; } + +type T15 = ReturnType; // C +>T15 : C +>ReturnType : ReturnType +>C : typeof C + +type T16 = ReturnType; // any +>T16 : any +>ReturnType : ReturnType + +type T17 = ReturnType; // any +>T17 : any +>ReturnType : ReturnType + +type T18 = ReturnType; // Error +>T18 : any +>ReturnType : ReturnType + +type T19 = ReturnType; // any +>T19 : any +>ReturnType : ReturnType +>Function : Function + +type ArgumentType any> = T extends (a: infer A) => any ? A : any; +>ArgumentType : ArgumentType +>T : T +>x : any +>T : T +>a : A +>A : A +>A : A + +type T20 = ArgumentType<() => void>; // never +>T20 : never +>ArgumentType : ArgumentType + +type T21 = ArgumentType<(x: string) => number>; // string +>T21 : string +>ArgumentType : ArgumentType +>x : string + +type T22 = ArgumentType<(x?: string) => number>; // string | undefined +>T22 : string | undefined +>ArgumentType : ArgumentType +>x : string | undefined + +type T23 = ArgumentType<(...args: string[]) => number>; // string +>T23 : string +>ArgumentType : ArgumentType +>args : string[] + +type T24 = ArgumentType<(x: string, y: string) => number>; // Error +>T24 : any +>ArgumentType : ArgumentType +>x : string +>y : string + +type T25 = ArgumentType; // Error +>T25 : any +>ArgumentType : ArgumentType +>Function : Function + +type T26 = ArgumentType; // any +>T26 : any +>ArgumentType : ArgumentType + +type T27 = ArgumentType; // any +>T27 : any +>ArgumentType : ArgumentType + +type X1 = T extends { x: infer X, y: infer Y } ? [X, Y] : any; +>X1 : X1 +>T : T +>x : any +>y : any +>T : T +>x : X +>X : X +>y : Y +>Y : Y +>X : X +>Y : Y + +type T30 = X1<{ x: any, y: any }>; // [any, any] +>T30 : [any, any] +>X1 : X1 +>x : any +>y : any + +type T31 = X1<{ x: number, y: string }>; // [number, string] +>T31 : [number, string] +>X1 : X1 +>x : number +>y : string + +type T32 = X1<{ x: number, y: string, z: boolean }>; // [number, string] +>T32 : [number, string] +>X1 : X1 +>x : number +>y : string +>z : boolean + +type X2 = T extends { a: infer U, b: infer U } ? U : never; +>X2 : X2 +>T : T +>T : T +>a : U +>U : U +>b : U +>U : U +>U : U + +type T40 = X2<{}>; // never +>T40 : never +>X2 : X2 + +type T41 = X2<{ a: string }>; // never +>T41 : never +>X2 : X2 +>a : string + +type T42 = X2<{ a: string, b: string }>; // string +>T42 : string +>X2 : X2 +>a : string +>b : string + +type T43 = X2<{ a: number, b: string }>; // string | number +>T43 : string | number +>X2 : X2 +>a : number +>b : string + +type T44 = X2<{ a: number, b: string, c: boolean }>; // string | number +>T44 : string | number +>X2 : X2 +>a : number +>b : string +>c : boolean + +type X3 = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never; +>X3 : X3 +>T : T +>T : T +>a : (x: U) => void +>x : U +>U : U +>b : (x: U) => void +>x : U +>U : U +>U : U + +type T50 = X3<{}>; // never +>T50 : never +>X3 : X3 + +type T51 = X3<{ a: (x: string) => void }>; // never +>T51 : never +>X3 : X3 +>a : (x: string) => void +>x : string + +type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string +>T52 : string +>X3 : X3 +>a : (x: string) => void +>x : string +>b : (x: string) => void +>x : string + +type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number +>T53 : number & string +>X3 : X3 +>a : (x: number) => void +>x : number +>b : (x: string) => void +>x : string + +type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number +>T54 : number +>X3 : X3 +>a : (x: number) => void +>x : number +>b : () => void + +type T60 = infer U; // Error +>T60 : U +>U : U + +type T61 = infer A extends infer B ? infer C : infer D; // Error +>T61 : never +>T : T +>A : A +>B : B +>C : C +>D : D + +type T62 = U extends (infer U)[] ? U : U; // Error +>T62 : any +>T : T +>U : No type information available! +>U : U +>U : U +>U : No type information available! + diff --git a/tests/cases/conformance/types/conditional/conditionalTypes1.ts b/tests/cases/conformance/types/conditional/conditionalTypes1.ts index d882b4c8bf3..6f4e7dc4188 100644 --- a/tests/cases/conformance/types/conditional/conditionalTypes1.ts +++ b/tests/cases/conformance/types/conditional/conditionalTypes1.ts @@ -196,3 +196,7 @@ type O6 = Or; // boolean type O7 = Or; // true type O8 = Or; // true type O9 = Or; // boolean + +type T40 = never extends never ? true : false; // true +type T41 = number extends never ? true : false; // false +type T42 = never extends number ? true : false; // boolean diff --git a/tests/cases/conformance/types/conditional/inferTypes1.ts b/tests/cases/conformance/types/conditional/inferTypes1.ts new file mode 100644 index 00000000000..25552a68acf --- /dev/null +++ b/tests/cases/conformance/types/conditional/inferTypes1.ts @@ -0,0 +1,75 @@ +// @strict: true +// @declaration: true + +type Unpacked = + T extends (infer U)[] ? U : + T extends (...args: any[]) => infer U ? U : + T extends Promise ? U : + T; + +type T00 = Unpacked; // string +type T01 = Unpacked; // string +type T02 = Unpacked<() => string>; // string +type T03 = Unpacked>; // string +type T04 = Unpacked[]>>; // string +type T05 = Unpacked; // any +type T06 = Unpacked; // never + +type ReturnType = T extends ((...args: any[]) => infer R) | (new (...args: any[]) => infer R) ? R : any; + +function f1(s: string) { + return { a: 1, b: s }; +} + +class C { + x = 0; + y = 0; +} + +type T10 = ReturnType<() => string>; // string +type T11 = ReturnType<(s: string) => void>; // void +type T12 = ReturnType<(() => T)>; // {} +type T13 = ReturnType<(() => T)>; // number[] +type T14 = ReturnType; // { a: number, b: string } +type T15 = ReturnType; // C +type T16 = ReturnType; // any +type T17 = ReturnType; // any +type T18 = ReturnType; // Error +type T19 = ReturnType; // any + +type ArgumentType any> = T extends (a: infer A) => any ? A : any; + +type T20 = ArgumentType<() => void>; // never +type T21 = ArgumentType<(x: string) => number>; // string +type T22 = ArgumentType<(x?: string) => number>; // string | undefined +type T23 = ArgumentType<(...args: string[]) => number>; // string +type T24 = ArgumentType<(x: string, y: string) => number>; // Error +type T25 = ArgumentType; // Error +type T26 = ArgumentType; // any +type T27 = ArgumentType; // any + +type X1 = T extends { x: infer X, y: infer Y } ? [X, Y] : any; + +type T30 = X1<{ x: any, y: any }>; // [any, any] +type T31 = X1<{ x: number, y: string }>; // [number, string] +type T32 = X1<{ x: number, y: string, z: boolean }>; // [number, string] + +type X2 = T extends { a: infer U, b: infer U } ? U : never; + +type T40 = X2<{}>; // never +type T41 = X2<{ a: string }>; // never +type T42 = X2<{ a: string, b: string }>; // string +type T43 = X2<{ a: number, b: string }>; // string | number +type T44 = X2<{ a: number, b: string, c: boolean }>; // string | number + +type X3 = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never; + +type T50 = X3<{}>; // never +type T51 = X3<{ a: (x: string) => void }>; // never +type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string +type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number +type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number + +type T60 = infer U; // Error +type T61 = infer A extends infer B ? infer C : infer D; // Error +type T62 = U extends (infer U)[] ? U : U; // Error diff --git a/tests/cases/fourslash/completionInJSDocFunctionNew.ts b/tests/cases/fourslash/completionInJSDocFunctionNew.ts index 1266eb5fad3..2d2b47bad3f 100644 --- a/tests/cases/fourslash/completionInJSDocFunctionNew.ts +++ b/tests/cases/fourslash/completionInJSDocFunctionNew.ts @@ -6,5 +6,4 @@ ////var f = function () { return new/**/; } goTo.marker(); -verify.completionListCount(107); verify.completionListContains('new'); diff --git a/tests/cases/fourslash/completionInJSDocFunctionThis.ts b/tests/cases/fourslash/completionInJSDocFunctionThis.ts index 57cf08c9ff3..2eedbc8e062 100644 --- a/tests/cases/fourslash/completionInJSDocFunctionThis.ts +++ b/tests/cases/fourslash/completionInJSDocFunctionThis.ts @@ -5,5 +5,4 @@ ////var f = function (s) { return this/**/; } goTo.marker(); -verify.completionListCount(108); verify.completionListContains('this')