diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index d366ff3dfe524..d196d8add4d7b 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 { @@ -3440,6 +3470,8 @@ namespace ts { case SyntaxKind.TupleType: 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 eccdef8fff6d4..05da314a8161c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -306,6 +306,7 @@ namespace ts { const intersectionTypes = createMap(); const literalTypes = createMap(); const indexedAccessTypes = createMap(); + const conditionalTypes = createMap(); const evolvingArrayTypes: EvolvingArrayType[] = []; const undefinedProperties = createMap() as UnderscoreEscapedMap; @@ -541,6 +542,7 @@ namespace ts { const subtypeRelation = createMap(); const assignableRelation = createMap(); + const definitelyAssignableRelation = createMap(); const comparableRelation = createMap(); const identityRelation = createMap(); const enumRelation = createMap(); @@ -1187,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; @@ -2955,6 +2962,16 @@ namespace ts { const indexTypeNode = typeToTypeNodeHelper((type).indexType, context); return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); } + if (type.flags & TypeFlags.Conditional) { + const checkTypeNode = typeToTypeNodeHelper((type).checkType, context); + const extendsTypeNode = typeToTypeNodeHelper((type).extendsType, context); + const trueTypeNode = typeToTypeNodeHelper((type).trueType, context); + const falseTypeNode = typeToTypeNodeHelper((type).falseType, context); + return createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode); + } + if (type.flags & TypeFlags.Substitution) { + return typeToTypeNodeHelper((type).typeParameter, context); + } Debug.fail("Should be unreachable."); @@ -4666,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) && @@ -5829,7 +5850,7 @@ namespace ts { // and T as the template type. const typeParameter = getTypeParameterFromMappedType(type); const constraintType = getConstraintTypeFromMappedType(type); - const templateType = getTemplateTypeFromMappedType(type); + const templateType = getTemplateTypeFromMappedType(type.target || type); const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T' const templateReadonly = !!type.declaration.readonlyToken; const templateOptional = !!type.declaration.questionToken; @@ -5848,7 +5869,7 @@ namespace ts { // First, if the constraint type is a type parameter, obtain the base constraint. Then, // if the key type is a 'keyof X', obtain 'keyof C' where C is the base constraint of X. // Finally, iterate over the constituents of the resulting iteration type. - const keyType = constraintType.flags & TypeFlags.TypeVariable ? getApparentType(constraintType) : constraintType; + const keyType = constraintType.flags & TypeFlags.InstantiableNonPrimitive ? getApparentType(constraintType) : constraintType; const iterationType = keyType.flags & TypeFlags.Index ? getIndexType(getApparentType((keyType).type)) : keyType; forEachType(iterationType, addMemberForKeyType); } @@ -6048,10 +6069,11 @@ namespace ts { return arrayFrom(props.values()); } - function getConstraintOfType(type: TypeVariable | UnionOrIntersectionType): Type { + function getConstraintOfType(type: InstantiableType | UnionOrIntersectionType): Type { return type.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(type) : type.flags & TypeFlags.IndexedAccess ? getConstraintOfIndexedAccess(type) : - getBaseConstraintOfType(type); + type.flags & TypeFlags.Conditional ? getConstraintOfConditionalType(type) : + getBaseConstraintOfType(type); } function getConstraintOfTypeParameter(typeParameter: TypeParameter): Type { @@ -6073,9 +6095,33 @@ namespace ts { return baseObjectType || baseIndexType ? getIndexedAccessType(baseObjectType || type.objectType, baseIndexType || type.indexType) : undefined; } + function getDefaultConstraintOfConditionalType(type: ConditionalType) { + return getUnionType([type.trueType, type.falseType]); + } + + function getConstraintOfDistributiveConditionalType(type: ConditionalType) { + // Check if we have a conditional type of the form 'T extends U ? X : Y', where T is a constrained + // type parameter. If so, create an instantiation of the conditional type where T is replaced + // with its constraint. We do this because if the constraint is a union type it will be distributed + // over the conditional type and possibly reduced. For example, 'T extends undefined ? never : T' + // removes 'undefined' from T. + const checkType = type.checkType; + if (checkType.flags & TypeFlags.TypeParameter) { + const constraint = getConstraintOfTypeParameter(checkType); + if (constraint) { + return instantiateType(type, createTypeMapper([checkType], [constraint])); + } + } + return undefined; + } + + function getConstraintOfConditionalType(type: ConditionalType) { + return getConstraintOfDistributiveConditionalType(type) || getDefaultConstraintOfConditionalType(type); + } + function getBaseConstraintOfType(type: Type): Type { - if (type.flags & (TypeFlags.TypeVariable | TypeFlags.UnionOrIntersection)) { - const constraint = getResolvedBaseConstraint(type); + if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection)) { + const constraint = getResolvedBaseConstraint(type); if (constraint !== noConstraintType && constraint !== circularConstraintType) { return constraint; } @@ -6086,7 +6132,7 @@ namespace ts { return undefined; } - function hasNonCircularBaseConstraint(type: TypeVariable): boolean { + function hasNonCircularBaseConstraint(type: InstantiableType): boolean { return getResolvedBaseConstraint(type) !== circularConstraintType; } @@ -6095,7 +6141,7 @@ namespace ts { * type variable has no constraint, and the circularConstraintType singleton is returned if the constraint * circularly references the type variable. */ - function getResolvedBaseConstraint(type: TypeVariable | UnionOrIntersectionType): Type { + function getResolvedBaseConstraint(type: InstantiableType | UnionOrIntersectionType): Type { let circular: boolean; if (!type.resolvedBaseConstraint) { const constraint = getBaseConstraint(type); @@ -6149,6 +6195,12 @@ namespace ts { const baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined; return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined; } + if (t.flags & TypeFlags.Conditional) { + return getBaseConstraint(getConstraintOfConditionalType(t)); + } + if (t.flags & TypeFlags.Substitution) { + return getBaseConstraint((t).substitute); + } if (isGenericMappedType(t)) { return emptyObjectType; } @@ -6213,7 +6265,7 @@ namespace ts { * type itself. Note that the apparent type of a union type is the union type itself. */ function getApparentType(type: Type): Type { - const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfType(type) || emptyObjectType : type; + const t = type.flags & TypeFlags.Instantiable ? getBaseConstraintOfType(type) || emptyObjectType : type; return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(t) : t.flags & TypeFlags.StringLike ? globalStringType : t.flags & TypeFlags.NumberLike ? globalNumberType : @@ -7127,7 +7179,7 @@ namespace ts { error(node, Diagnostics.Type_0_is_not_generic, symbolToString(symbol)); return unknownType; } - return res; + return res.flags & TypeFlags.TypeParameter ? getConstrainedTypeParameter(res, node) : res; } if (!(symbol.flags & SymbolFlags.Value && isJSDocTypeReference(node))) { @@ -7166,6 +7218,27 @@ namespace ts { } } + function getSubstitutionType(typeParameter: TypeParameter, substitute: Type) { + const result = createType(TypeFlags.Substitution); + result.typeParameter = typeParameter; + result.substitute = substitute; + return result; + } + + function getConstrainedTypeParameter(typeParameter: TypeParameter, node: Node) { + let constraints: Type[]; + while (isTypeNode(node)) { + const parent = node.parent; + if (parent.kind === SyntaxKind.ConditionalType && node === (parent).trueType) { + if (getTypeFromTypeNode((parent).checkType) === typeParameter) { + constraints = append(constraints, getTypeFromTypeNode((parent).extendsType)); + } + } + node = parent; + } + return constraints ? getSubstitutionType(typeParameter, getIntersectionType(append(constraints, typeParameter))) : typeParameter; + } + function isJSDocTypeReference(node: TypeReferenceType): node is TypeReferenceNode { return node.flags & NodeFlags.JSDoc && node.kind === SyntaxKind.TypeReference; } @@ -7798,7 +7871,7 @@ namespace ts { return links.resolvedType; } - function getIndexTypeForGenericType(type: TypeVariable | UnionOrIntersectionType) { + function getIndexTypeForGenericType(type: InstantiableType | UnionOrIntersectionType) { if (!type.resolvedIndexType) { type.resolvedIndexType = createType(TypeFlags.Index); type.resolvedIndexType.type = type; @@ -7817,10 +7890,10 @@ namespace ts { } function getIndexType(type: Type): Type { - return maybeTypeOfKind(type, TypeFlags.TypeVariable) ? getIndexTypeForGenericType(type) : + return maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type) : getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : - type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringType : - getLiteralTypeFromPropertyNames(type); + type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringType : + getLiteralTypeFromPropertyNames(type); } function getIndexTypeOrString(type: Type): Type { @@ -7916,16 +7989,11 @@ namespace ts { } function isGenericObjectType(type: Type): boolean { - return type.flags & TypeFlags.TypeVariable ? true : - getObjectFlags(type) & ObjectFlags.Mapped ? isGenericIndexType(getConstraintTypeFromMappedType(type)) : - type.flags & TypeFlags.UnionOrIntersection ? forEach((type).types, isGenericObjectType) : - false; + return maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive | TypeFlags.GenericMappedType); } function isGenericIndexType(type: Type): boolean { - return type.flags & (TypeFlags.TypeVariable | TypeFlags.Index) ? true : - type.flags & TypeFlags.UnionOrIntersection ? forEach((type).types, isGenericIndexType) : - false; + return maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive | TypeFlags.Index); } // Return true if the given type is a non-generic object type with a string index signature and no @@ -8060,6 +8128,108 @@ namespace ts { return links.resolvedType; } + function getActualTypeParameter(type: Type) { + return type.flags & TypeFlags.Substitution ? (type).typeParameter : 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; + type.aliasTypeArguments = aliasTypeArguments; + return type; + } + + 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); + const falseType = instantiateType(baseFalseType, mapper); + const id = target && (target.id + "," + erasedCheckType.id + "," + extendsType.id + "," + trueType.id + "," + falseType.id); + const cached = id && conditionalTypes.get(id); + if (cached) { + return cached; + } + const result = createConditionalType(erasedCheckType, extendsType, trueType, falseType, + 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), + 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) { @@ -8095,7 +8265,7 @@ namespace ts { * this function should be called in a left folding style, with left = previous result of getSpreadType * and right = the new element to be spread. */ - function getSpreadType(left: Type, right: Type, symbol: Symbol, propagatedFlags: TypeFlags): Type { + function getSpreadType(left: Type, right: Type, symbol: Symbol, typeFlags: TypeFlags, objectFlags: ObjectFlags): Type { if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) { return anyType; } @@ -8106,10 +8276,10 @@ namespace ts { return left; } if (left.flags & TypeFlags.Union) { - return mapType(left, t => getSpreadType(t, right, symbol, propagatedFlags)); + return mapType(left, t => getSpreadType(t, right, symbol, typeFlags, objectFlags)); } if (right.flags & TypeFlags.Union) { - return mapType(right, t => getSpreadType(left, t, symbol, propagatedFlags)); + return mapType(right, t => getSpreadType(left, t, symbol, typeFlags, objectFlags)); } if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive)) { return left; @@ -8172,8 +8342,8 @@ namespace ts { emptyArray, getNonReadonlyIndexSignature(stringIndexInfo), getNonReadonlyIndexSignature(numberIndexInfo)); - spread.flags |= propagatedFlags | TypeFlags.ContainsObjectLiteral; - (spread as ObjectType).objectFlags |= (ObjectFlags.ObjectLiteral | ObjectFlags.ContainsSpread); + spread.flags |= typeFlags | TypeFlags.ContainsObjectLiteral; + (spread as ObjectType).objectFlags |= objectFlags | (ObjectFlags.ObjectLiteral | ObjectFlags.ContainsSpread); return spread; } @@ -8348,6 +8518,10 @@ namespace ts { return getTypeFromIndexedAccessTypeNode(node); case SyntaxKind.MappedType: 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: @@ -8441,6 +8615,10 @@ namespace ts { return t => t === source ? target : baseMapper(t); } + function anyMapper(type: Type) { + return type.flags & TypeFlags.TypeParameter ? anyType : type; + } + function cloneTypeParameter(typeParameter: TypeParameter): TypeParameter { const result = createType(TypeFlags.TypeParameter); result.symbol = typeParameter.symbol; @@ -8495,7 +8673,7 @@ namespace ts { function instantiateSymbol(symbol: Symbol, mapper: TypeMapper): Symbol { const links = getSymbolLinks(symbol); - if (links.type && !maybeTypeOfKind(links.type, TypeFlags.Object | TypeFlags.TypeVariable | TypeFlags.Index)) { + if (links.type && !maybeTypeOfKind(links.type, TypeFlags.Object | TypeFlags.Instantiable)) { // If the type of the symbol is already resolved, and if that type could not possibly // be affected by instantiation, simply return the symbol itself. return symbol; @@ -8626,8 +8804,29 @@ namespace ts { return result; } + function getConditionalTypeInstantiation(type: ConditionalType, mapper: TypeMapper): Type { + const target = type.target || type; + const combinedMapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper; + // Check if we have a conditional type where the check type is a naked type parameter. If so, + // the conditional type is distributive over union types and when T is instantiated to a union + // type A | B, we produce (A extends U ? X : Y) | (B extends U ? X : Y). + const checkType = target.checkType; + if (checkType.flags & TypeFlags.TypeParameter) { + const instantiatedType = combinedMapper(checkType); + if (checkType !== instantiatedType && instantiatedType.flags & TypeFlags.Union) { + return mapType(instantiatedType, t => instantiateConditionalType(target, createReplacementMapper(checkType, t, combinedMapper))); + } + } + return instantiateConditionalType(target, combinedMapper); + } + + function instantiateConditionalType(type: ConditionalType, mapper: TypeMapper): Type { + 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 { - if (type && mapper !== identityMapper) { + if (type && mapper && mapper !== identityMapper) { if (type.flags & TypeFlags.TypeParameter) { return mapper(type); } @@ -8664,10 +8863,21 @@ namespace ts { if (type.flags & TypeFlags.IndexedAccess) { return getIndexedAccessType(instantiateType((type).objectType, mapper), instantiateType((type).indexType, mapper)); } + if (type.flags & TypeFlags.Conditional) { + return getConditionalTypeInstantiation(type, mapper); + } + if (type.flags & TypeFlags.Substitution) { + return mapper((type).typeParameter); + } } 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); } @@ -8785,7 +8995,7 @@ namespace ts { function isTypeDerivedFrom(source: Type, target: Type): boolean { return source.flags & TypeFlags.Union ? every((source).types, t => isTypeDerivedFrom(t, target)) : target.flags & TypeFlags.Union ? some((target).types, t => isTypeDerivedFrom(source, t)) : - source.flags & TypeFlags.TypeVariable ? isTypeDerivedFrom(getBaseConstraintOfType(source) || emptyObjectType, target) : + source.flags & TypeFlags.InstantiableNonPrimitive ? isTypeDerivedFrom(getBaseConstraintOfType(source) || emptyObjectType, target) : target === globalObjectType || target === globalFunctionType ? isTypeSubtypeOf(source, target) : hasBaseType(source, getTargetType(target)); } @@ -9095,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 @@ -9124,14 +9334,14 @@ namespace ts { return related === RelationComparisonResult.Succeeded; } } - if (source.flags & TypeFlags.StructuredOrTypeVariable || target.flags & TypeFlags.StructuredOrTypeVariable) { + if (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable) { return checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined); } return false; } function isIgnoredJsxProperty(source: Type, sourceProp: Symbol, targetMemberType: Type | undefined) { - return source.flags & TypeFlags.JsxAttributes && !(isUnhyphenatedJsxName(sourceProp.escapedName) || targetMemberType); + return getObjectFlags(source) & ObjectFlags.JsxAttributes && !(isUnhyphenatedJsxName(sourceProp.escapedName) || targetMemberType); } /** @@ -9263,6 +9473,13 @@ namespace ts { if (target.flags & TypeFlags.StringOrNumberLiteral && target.flags & TypeFlags.FreshLiteral) { target = (target).regularType; } + if (source.flags & TypeFlags.Substitution) { + source = relation === definitelyAssignableRelation ? (source).typeParameter : (source).substitute; + } + if (target.flags & TypeFlags.Substitution) { + target = (target).typeParameter; + } + // both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases if (source === target) return Ternary.True; @@ -9349,7 +9566,7 @@ namespace ts { // breaking the intersection apart. result = someTypeRelatedToType(source, target, /*reportErrors*/ false); } - if (!result && (source.flags & TypeFlags.StructuredOrTypeVariable || target.flags & TypeFlags.StructuredOrTypeVariable)) { + if (!result && (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable)) { if (result = recursiveTypeRelatedTo(source, target, reportErrors)) { errorInfo = saveErrorInfo; } @@ -9388,8 +9605,8 @@ 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 = !!(source.flags & TypeFlags.JsxAttributes); - if ((relation === assignableRelation || relation === comparableRelation) && + const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes); + if ((relation === assignableRelation || relation === definitelyAssignableRelation || relation === comparableRelation) && (isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))) { return false; } @@ -9658,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; @@ -9683,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; @@ -9692,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; @@ -9701,18 +9922,26 @@ namespace ts { } } } - else if (isGenericMappedType(target) && !isGenericMappedType(source) && getConstraintTypeFromMappedType(target) === getIndexType(source)) { + else if (isGenericMappedType(target)) { + // A source type T is related to a target type { [P in X]: T[P] } + const template = getTemplateTypeFromMappedType(target); + if (template.flags & TypeFlags.IndexedAccess && (template).objectType === source && + (template).indexType === getTypeParameterFromMappedType(target)) { + return Ternary.True; + } // A source type T is related to a target type { [P in keyof T]: X } if T[P] is related to X. - const indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(target)); - const templateType = getTemplateTypeFromMappedType(target); - if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) { - errorInfo = saveErrorInfo; - return result; + if (!isGenericMappedType(source) && getConstraintTypeFromMappedType(target) === getIndexType(source)) { + const indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(target)); + const templateType = getTemplateTypeFromMappedType(target); + if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) { + errorInfo = saveErrorInfo; + return result; + } } } 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) { @@ -9728,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; @@ -9746,9 +9975,24 @@ namespace ts { } } } + else if (source.flags & TypeFlags.Conditional) { + 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)) { + errorInfo = saveErrorInfo; + return result; + } + } else { if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (source).target === (target).target && - !(source.flags & TypeFlags.MarkerType || target.flags & TypeFlags.MarkerType)) { + !(getObjectFlags(source) & ObjectFlags.MarkerType || getObjectFlags(target) & ObjectFlags.MarkerType)) { // We have type references to the same generic type, and the type references are not marker // type references (which are intended by be compared structurally). Obtain the variance // information for the type parameters and relate the type arguments accordingly. @@ -9965,7 +10209,7 @@ namespace ts { } function hasCommonProperties(source: Type, target: Type) { - const isComparingJsxAttributes = !!(source.flags & TypeFlags.JsxAttributes); + const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes); for (const prop of getPropertiesOfType(source)) { if (isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) { return true; @@ -10212,7 +10456,7 @@ namespace ts { // type, and flag the result as a marker type reference. function getMarkerTypeReference(type: GenericType, source: TypeParameter, target: Type) { const result = createTypeReference(type, map(type.typeParameters, t => t === source ? target : t)); - result.flags |= TypeFlags.MarkerType; + result.objectFlags |= ObjectFlags.MarkerType; return result; } @@ -11003,7 +11247,7 @@ namespace ts { // results for union and intersection types for performance reasons. function couldContainTypeVariables(type: Type): boolean { const objectFlags = getObjectFlags(type); - return !!(type.flags & (TypeFlags.TypeVariable | TypeFlags.Index) || + return !!(type.flags & TypeFlags.Instantiable || objectFlags & ObjectFlags.Reference && forEach((type).typeArguments, couldContainTypeVariables) || objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) || objectFlags & ObjectFlags.Mapped || @@ -11085,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) { @@ -11103,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; @@ -11224,14 +11472,20 @@ namespace ts { inferFromTypes((source).objectType, (target).objectType); inferFromTypes((source).indexType, (target).indexType); } + else if (source.flags & TypeFlags.Conditional && target.flags & TypeFlags.Conditional) { + inferFromTypes((source).checkType, (target).checkType); + inferFromTypes((source).extendsType, (target).extendsType); + inferFromTypes((source).trueType, (target).trueType); + inferFromTypes((source).falseType, (target).falseType); + } else if (target.flags & TypeFlags.UnionOrIntersection) { const targetTypes = (target).types; let typeVariableCount = 0; - let typeVariable: TypeVariable; + let typeVariable: TypeParameter | IndexedAccessType; // First infer to each type in union or intersection that isn't a type variable for (const t of targetTypes) { if (getInferenceInfoForType(t)) { - typeVariable = t; + typeVariable = t; typeVariableCount++; } else { @@ -11256,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)) { @@ -11286,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; @@ -11813,7 +12069,7 @@ namespace ts { if (flags & TypeFlags.NonPrimitive) { return strictNullChecks ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts; } - if (flags & TypeFlags.TypeVariable) { + if (flags & TypeFlags.Instantiable) { return getTypeFacts(getBaseConstraintOfType(type) || emptyObjectType); } if (flags & TypeFlags.UnionOrIntersection) { @@ -12677,7 +12933,7 @@ namespace ts { if (isTypeSubtypeOf(targetType, type)) { return targetType; } - if (type.flags & TypeFlags.TypeVariable) { + if (type.flags & TypeFlags.Instantiable) { const constraint = getBaseConstraintOfType(type) || anyType; if (isTypeSubtypeOf(targetType, constraint)) { return getIntersectionType([type, targetType]); @@ -12942,7 +13198,7 @@ namespace ts { } function typeHasNullableConstraint(type: Type) { - return type.flags & TypeFlags.TypeVariable && maybeTypeOfKind(getBaseConstraintOfType(type) || emptyObjectType, TypeFlags.Nullable); + return type.flags & TypeFlags.InstantiableNonPrimitive && maybeTypeOfKind(getBaseConstraintOfType(type) || emptyObjectType, TypeFlags.Nullable); } function getApparentTypeForLocation(type: Type, node: Node) { @@ -14472,7 +14728,7 @@ namespace ts { checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign); } if (propertiesArray.length > 0) { - spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags); + spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags, /*objectFlags*/ 0); propertiesArray = []; propertiesTable = createSymbolTable(); hasComputedStringProperty = false; @@ -14484,7 +14740,7 @@ namespace ts { error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types); return unknownType; } - spread = getSpreadType(spread, type, node.symbol, propagatedFlags); + spread = getSpreadType(spread, type, node.symbol, propagatedFlags, /*objectFlags*/ 0); offset = i + 1; continue; } @@ -14529,7 +14785,7 @@ namespace ts { if (spread !== emptyObjectType) { if (propertiesArray.length > 0) { - spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags); + spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags, /*objectFlags*/ 0); } return spread; } @@ -14662,7 +14918,7 @@ namespace ts { else { Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute); if (attributesTable.size > 0) { - spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, TypeFlags.JsxAttributes); + spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, /*typeFlags*/ 0, ObjectFlags.JsxAttributes); attributesTable = createSymbolTable(); } const exprType = checkExpressionCached(attributeDecl.expression, checkMode); @@ -14670,7 +14926,7 @@ namespace ts { hasSpreadAnyType = true; } if (isValidSpreadType(exprType)) { - spread = getSpreadType(spread, exprType, openingLikeElement.symbol, TypeFlags.JsxAttributes); + spread = getSpreadType(spread, exprType, openingLikeElement.symbol, /*typeFlags*/ 0, ObjectFlags.JsxAttributes); } else { typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType; @@ -14680,7 +14936,7 @@ namespace ts { if (!hasSpreadAnyType) { if (attributesTable.size > 0) { - spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, TypeFlags.JsxAttributes); + spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, /*typeFlags*/ 0, ObjectFlags.JsxAttributes); } } @@ -14705,7 +14961,8 @@ namespace ts { createArrayType(getUnionType(childrenTypes)); const childPropMap = createSymbolTable(); childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol); - spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined), attributes.symbol, TypeFlags.JsxAttributes); + spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined), + attributes.symbol, /*typeFlags*/ 0, ObjectFlags.JsxAttributes); } } @@ -14722,8 +14979,8 @@ namespace ts { */ function createJsxAttributesType() { const result = createAnonymousType(attributes.symbol, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); - result.flags |= TypeFlags.JsxAttributes | TypeFlags.ContainsObjectLiteral; - result.objectFlags |= ObjectFlags.ObjectLiteral; + result.flags |= TypeFlags.ContainsObjectLiteral; + result.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.JsxAttributes; return result; } } @@ -17610,7 +17867,7 @@ namespace ts { const anonymousSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type); const defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); anonymousSymbol.type = defaultContainingObject; - synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*propegatedFlags*/ 0) : defaultContainingObject; + synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*typeFLags*/ 0, /*objectFlags*/ 0) : defaultContainingObject; } else { synthType.syntheticType = type; @@ -18337,7 +18594,7 @@ namespace ts { // Return true if type might be of the given kind. A union or intersection type might be of a given // kind if at least one constituent type is of the given kind. function maybeTypeOfKind(type: Type, kind: TypeFlags): boolean { - if (type.flags & kind) { + if (type.flags & kind || kind & TypeFlags.GenericMappedType && isGenericMappedType(type)) { return true; } if (type.flags & TypeFlags.UnionOrIntersection) { @@ -18416,7 +18673,7 @@ namespace ts { if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind(leftType, TypeFlags.NumberLike | TypeFlags.ESSymbolLike))) { error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol); } - if (!isTypeAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.TypeVariable)) { + if (!isTypeAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive)) { error(right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } return booleanType; @@ -19015,7 +19272,7 @@ namespace ts { const types = (contextualType).types; return some(types, t => isLiteralOfContextualType(candidateType, t)); } - if (contextualType.flags & TypeFlags.TypeVariable) { + if (contextualType.flags & TypeFlags.InstantiableNonPrimitive) { // If the contextual type is a type variable constrained to a primitive type, consider // this a literal context for literals of that primitive type. For example, given a // type parameter 'T extends string', infer string literal types for T. @@ -19981,6 +20238,17 @@ namespace ts { checkSourceElement(node.type); } + function checkConditionalType(node: ConditionalTypeNode) { + 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); } @@ -21768,7 +22036,7 @@ namespace ts { // unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved // in this case error about missing name is already reported - do not report extra one - if (!isTypeAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.TypeVariable)) { + if (!isTypeAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive)) { error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter); } @@ -23690,6 +23958,10 @@ namespace ts { return checkSourceElement((node).type); case SyntaxKind.TypeOperator: 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/core.ts b/src/compiler/core.ts index 4b76e2742cdd0..f6f2667c276af 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -439,23 +439,21 @@ namespace ts { export function sameMap(array: T[], f: (x: T, i: number) => T): T[]; export function sameMap(array: ReadonlyArray, f: (x: T, i: number) => T): ReadonlyArray; export function sameMap(array: T[], f: (x: T, i: number) => T): T[] { - let result: T[]; if (array) { for (let i = 0; i < array.length; i++) { - if (result) { - result.push(f(array[i], i)); - } - else { - const item = array[i]; - const mapped = f(item, i); - if (item !== mapped) { - result = array.slice(0, i); - result.push(mapped); + const item = array[i]; + const mapped = f(item, i); + if (item !== mapped) { + const result = array.slice(0, i); + result.push(mapped); + for (i++; i < array.length; i++) { + result.push(f(array[i], i)); } + return result; } } } - return result || array; + return array; } /** diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 96ef4afc8da05..24646ff31eb44 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -450,6 +450,10 @@ namespace ts { return emitUnionType(type); case SyntaxKind.IntersectionType: return emitIntersectionType(type); + case SyntaxKind.ConditionalType: + return emitConditionalType(type); + case SyntaxKind.InferType: + return emitInferType(type); case SyntaxKind.ParenthesizedType: return emitParenType(type); case SyntaxKind.TypeOperator: @@ -545,6 +549,24 @@ namespace ts { emitSeparatedList(type.types, " & ", emitType); } + function emitConditionalType(node: ConditionalTypeNode) { + emitType(node.checkType); + 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 6fffd576e7caf..77614dd757390 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 03ff63a421123..58aa2c7a56308 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -600,6 +600,10 @@ namespace ts { return emitUnionType(node); case SyntaxKind.IntersectionType: return emitIntersectionType(node); + case SyntaxKind.ConditionalType: + return emitConditionalType(node); + case SyntaxKind.InferType: + return emitInferType(node); case SyntaxKind.ParenthesizedType: return emitParenthesizedType(node); case SyntaxKind.ExpressionWithTypeArguments: @@ -1190,6 +1194,28 @@ namespace ts { emitList(node, node.types, ListFormat.IntersectionTypeConstituents); } + function emitConditionalType(node: ConditionalTypeNode) { + emit(node.checkType); + writeSpace(); + writeKeyword("extends"); + writeSpace(); + emit(node.extendsType); + writeSpace(); + writePunctuation("?"); + writeSpace(); + emit(node.trueType); + 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 32f6877a15269..165c70b37e610 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -731,6 +731,36 @@ namespace ts { : node; } + export function createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) { + const node = createSynthesizedNode(SyntaxKind.ConditionalType) as ConditionalTypeNode; + node.checkType = parenthesizeConditionalTypeMember(checkType); + node.extendsType = parenthesizeConditionalTypeMember(extendsType); + node.trueType = trueType; + node.falseType = falseType; + return node; + } + + export function updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) { + return node.checkType !== checkType + || node.extendsType !== extendsType + || node.trueType !== trueType + || node.falseType !== falseType + ? updateNode(createConditionalTypeNode(checkType, extendsType, trueType, falseType), node) + : 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; @@ -4094,6 +4124,10 @@ namespace ts { return expression; } + export function parenthesizeConditionalTypeMember(member: TypeNode) { + return member.kind === SyntaxKind.ConditionalType ? createParenthesizedType(member) : member; + } + export function parenthesizeElementTypeMember(member: TypeNode) { switch (member.kind) { case SyntaxKind.UnionType: @@ -4102,7 +4136,7 @@ namespace ts { case SyntaxKind.ConstructorType: return createParenthesizedType(member); } - return member; + return parenthesizeConditionalTypeMember(member); } export function parenthesizeArrayTypeMember(member: TypeNode) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ff89c55fc1e1a..5b8504eb6dc41 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -175,6 +175,13 @@ namespace ts { case SyntaxKind.UnionType: case SyntaxKind.IntersectionType: return visitNodes(cbNode, cbNodes, (node).types); + case SyntaxKind.ConditionalType: + return visitNode(cbNode, (node).checkType) || + 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); @@ -1494,6 +1501,11 @@ namespace ts { return isStartOfExpression(); } + function nextTokenIsStartOfType() { + nextToken(); + return isStartOfType(); + } + // True if positioned at a list terminator function isListTerminator(kind: ParsingContext): boolean { if (token() === SyntaxKind.EndOfFileToken) { @@ -2757,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); @@ -2789,6 +2802,10 @@ namespace ts { type = createJSDocPostfixType(SyntaxKind.JSDocNonNullableType, type); break; case SyntaxKind.QuestionToken: + // If not in JSDoc and next token is start of a type we have a conditional type + if (!(contextFlags & NodeFlags.JSDoc) && lookAhead(nextTokenIsStartOfType)) { + return type; + } type = createJSDocPostfixType(SyntaxKind.JSDocNullableType, type); break; case SyntaxKind.OpenBracketToken: @@ -2829,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(); @@ -2950,14 +2978,26 @@ namespace ts { return doOutsideOfContext(NodeFlags.TypeExcludesFlags, parseTypeWorker); } - function parseTypeWorker(): TypeNode { + function parseTypeWorker(noConditionalTypes?: boolean): TypeNode { if (isStartOfFunctionType()) { return parseFunctionOrConstructorType(SyntaxKind.FunctionType); } if (token() === SyntaxKind.NewKeyword) { return parseFunctionOrConstructorType(SyntaxKind.ConstructorType); } - return parseUnionTypeOrHigher(); + const type = parseUnionTypeOrHigher(); + if (!noConditionalTypes && parseOptional(SyntaxKind.ExtendsKeyword)) { + const node = createNode(SyntaxKind.ConditionalType, type.pos); + node.checkType = type; + // The type following 'extends' is not permitted to be another conditional type + node.extendsType = parseTypeWorker(/*noConditionalTypes*/ true); + parseExpected(SyntaxKind.QuestionToken); + node.trueType = parseTypeWorker(); + parseExpected(SyntaxKind.ColonToken); + node.falseType = parseTypeWorker(); + return finishNode(node); + } + return type; } function parseTypeAnnotation(): TypeNode { diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 6b0d10223fdd8..cdb055bb7326d 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/transformers/ts.ts b/src/compiler/transformers/ts.ts index f6c5d145a90a9..0e70b3099c005 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -385,6 +385,7 @@ namespace ts { case SyntaxKind.TypeReference: case SyntaxKind.UnionType: case SyntaxKind.IntersectionType: + case SyntaxKind.ConditionalType: case SyntaxKind.ParenthesizedType: case SyntaxKind.ThisType: case SyntaxKind.TypeOperator: diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 30eb518961176..0a1c49a93c303 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -215,6 +215,7 @@ namespace ts { ConstructorKeyword, DeclareKeyword, GetKeyword, + InferKeyword, IsKeyword, KeyOfKeyword, ModuleKeyword, @@ -265,6 +266,8 @@ namespace ts { TupleType, UnionType, IntersectionType, + ConditionalType, + InferType, ParenthesizedType, ThisType, TypeOperator, @@ -770,7 +773,7 @@ namespace ts { export interface TypeParameterDeclaration extends NamedDeclaration { kind: SyntaxKind.TypeParameter; - parent?: DeclarationWithTypeParameters; + parent?: DeclarationWithTypeParameters | InferTypeNode; name: Identifier; constraint?: TypeNode; default?: TypeNode; @@ -1116,6 +1119,19 @@ namespace ts { types: NodeArray; } + export interface ConditionalTypeNode extends TypeNode { + kind: SyntaxKind.ConditionalType; + checkType: TypeNode; + extendsType: TypeNode; + trueType: TypeNode; + falseType: TypeNode; + } + + export interface InferTypeNode extends TypeNode { + kind: SyntaxKind.InferType; + typeParameter: TypeParameterDeclaration; + } + export interface ParenthesizedTypeNode extends TypeNode { kind: SyntaxKind.ParenthesizedType; type: TypeNode; @@ -3484,18 +3500,19 @@ namespace ts { Intersection = 1 << 18, // Intersection (T & U) Index = 1 << 19, // keyof T IndexedAccess = 1 << 20, // T[K] + Conditional = 1 << 21, // T extends U ? X : Y + Substitution = 1 << 22, // Type parameter substitution /* @internal */ - FreshLiteral = 1 << 21, // Fresh literal or unique type + FreshLiteral = 1 << 23, // Fresh literal or unique type /* @internal */ - ContainsWideningType = 1 << 22, // Type is or contains undefined or null widening type + ContainsWideningType = 1 << 24, // Type is or contains undefined or null widening type /* @internal */ - ContainsObjectLiteral = 1 << 23, // Type is or contains object literal type + ContainsObjectLiteral = 1 << 25, // Type is or contains object literal type /* @internal */ - ContainsAnyFunctionType = 1 << 24, // Type is or contains the anyFunctionType - NonPrimitive = 1 << 25, // intrinsic object type + ContainsAnyFunctionType = 1 << 26, // Type is or contains the anyFunctionType + NonPrimitive = 1 << 27, // intrinsic object type /* @internal */ - JsxAttributes = 1 << 26, // Jsx attributes type - MarkerType = 1 << 27, // Marker type used for variance probing + GenericMappedType = 1 << 29, // Flag used by maybeTypeOfKind /* @internal */ Nullable = Undefined | Null, @@ -3518,17 +3535,21 @@ namespace ts { ESSymbolLike = ESSymbol | UniqueESSymbol, UnionOrIntersection = Union | Intersection, StructuredType = Object | Union | Intersection, - StructuredOrTypeVariable = StructuredType | TypeParameter | Index | IndexedAccess, TypeVariable = TypeParameter | IndexedAccess, + InstantiableNonPrimitive = TypeVariable | Conditional | Substitution, + InstantiablePrimitive = Index, + Instantiable = InstantiableNonPrimitive | InstantiablePrimitive, + StructuredOrInstantiable = StructuredType | Instantiable, // 'Narrowable' types are types where narrowing actually narrows. // This *should* be every type other than null, undefined, void, and never - Narrowable = Any | StructuredType | TypeParameter | Index | IndexedAccess | StringLike | NumberLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive, + Narrowable = Any | StructuredOrInstantiable | StringLike | NumberLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive, NotUnionOrUnit = Any | ESSymbol | Object | NonPrimitive, /* @internal */ RequiresWidening = ContainsWideningType | ContainsObjectLiteral, /* @internal */ PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | ContainsAnyFunctionType, + /* @internal */ } export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; @@ -3542,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 */ @@ -3587,7 +3610,9 @@ namespace ts { EvolvingArray = 1 << 8, // Evolving array type ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties ContainsSpread = 1 << 10, // Object literal contains spread operation - ReverseMapped = 1 << 11, // Object contains a property from a reverse-mapped type + ReverseMapped = 1 << 11, // Object contains a property from a reverse-mapped type + JsxAttributes = 1 << 12, // Jsx attributes type + MarkerType = 1 << 13, // Marker type used for variance probing ClassOrInterface = Class | Interface } @@ -3741,7 +3766,7 @@ namespace ts { syntheticType?: Type; } - export interface TypeVariable extends Type { + export interface InstantiableType extends Type { /* @internal */ resolvedBaseConstraint?: Type; /* @internal */ @@ -3749,7 +3774,7 @@ namespace ts { } // Type parameters (TypeFlags.TypeParameter) - export interface TypeParameter extends TypeVariable { + export interface TypeParameter extends InstantiableType { /** Retrieve using getConstraintFromTypeParameter */ /* @internal */ constraint?: Type; // Constraint @@ -3767,15 +3792,40 @@ namespace ts { // Indexed access types (TypeFlags.IndexedAccess) // Possible forms are T[xxx], xxx[T], or xxx[keyof T], where T is a type variable - export interface IndexedAccessType extends TypeVariable { + export interface IndexedAccessType extends InstantiableType { objectType: Type; indexType: Type; constraint?: Type; } // keyof T types (TypeFlags.Index) - export interface IndexType extends Type { - type: TypeVariable | UnionOrIntersectionType; + export interface IndexType extends InstantiableType { + type: InstantiableType | UnionOrIntersectionType; + } + + // T extends U ? X : Y (TypeFlags.Conditional) + export interface ConditionalType extends InstantiableType { + checkType: Type; + extendsType: Type; + trueType: Type; + falseType: Type; + /* @internal */ + inferTypeParameters: TypeParameter[]; + /* @internal */ + target?: ConditionalType; + /* @internal */ + mapper?: TypeMapper; + } + + // Type parameter substitution (TypeFlags.Substitution) + // Substitution types are created for type parameter references that occur in the true branch + // of a conditional type. For example, in 'T extends string ? Foo : Bar', the reference to + // T in Foo is resolved as a substitution type that substitutes 'string & T' for T. Thus, if + // Foo has a 'string' constraint on its type parameter, T will satisfy it. Substitution types + // disappear upon instantiation (just like type parameters). + export interface SubstitutionType extends InstantiableType { + typeParameter: TypeParameter; // Target type parameter + substitute: Type; // Type to substitute for type parameter } export const enum SignatureKind { @@ -3837,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 f2874b6b66595..fb85f46fbd07f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4621,6 +4621,14 @@ namespace ts { return node.kind === SyntaxKind.IntersectionType; } + export function isConditionalTypeNode(node: Node): node is ConditionalTypeNode { + 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 12b5d4f1b07b7..9c1462e7ec6a6 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -387,6 +387,17 @@ namespace ts { return updateIntersectionTypeNode(node, nodesVisitor((node).types, visitor, isTypeNode)); + case SyntaxKind.ConditionalType: + return updateConditionalTypeNode(node, + visitNode((node).checkType, visitor, isTypeNode), + visitNode((node).extendsType, visitor, isTypeNode), + 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 09cf8199ddb99..9d3000d6b609a 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -187,177 +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, - ParenthesizedType = 169, - ThisType = 170, - TypeOperator = 171, - IndexedAccessType = 172, - MappedType = 173, - LiteralType = 174, - ObjectBindingPattern = 175, - ArrayBindingPattern = 176, - BindingElement = 177, - ArrayLiteralExpression = 178, - ObjectLiteralExpression = 179, - PropertyAccessExpression = 180, - ElementAccessExpression = 181, - CallExpression = 182, - NewExpression = 183, - TaggedTemplateExpression = 184, - TypeAssertionExpression = 185, - ParenthesizedExpression = 186, - FunctionExpression = 187, - ArrowFunction = 188, - DeleteExpression = 189, - TypeOfExpression = 190, - VoidExpression = 191, - AwaitExpression = 192, - PrefixUnaryExpression = 193, - PostfixUnaryExpression = 194, - BinaryExpression = 195, - ConditionalExpression = 196, - TemplateExpression = 197, - YieldExpression = 198, - SpreadElement = 199, - ClassExpression = 200, - OmittedExpression = 201, - ExpressionWithTypeArguments = 202, - AsExpression = 203, - NonNullExpression = 204, - MetaProperty = 205, - TemplateSpan = 206, - SemicolonClassElement = 207, - Block = 208, - VariableStatement = 209, - EmptyStatement = 210, - ExpressionStatement = 211, - IfStatement = 212, - DoStatement = 213, - WhileStatement = 214, - ForStatement = 215, - ForInStatement = 216, - ForOfStatement = 217, - ContinueStatement = 218, - BreakStatement = 219, - ReturnStatement = 220, - WithStatement = 221, - SwitchStatement = 222, - LabeledStatement = 223, - ThrowStatement = 224, - TryStatement = 225, - DebuggerStatement = 226, - VariableDeclaration = 227, - VariableDeclarationList = 228, - FunctionDeclaration = 229, - ClassDeclaration = 230, - InterfaceDeclaration = 231, - TypeAliasDeclaration = 232, - EnumDeclaration = 233, - ModuleDeclaration = 234, - ModuleBlock = 235, - CaseBlock = 236, - NamespaceExportDeclaration = 237, - ImportEqualsDeclaration = 238, - ImportDeclaration = 239, - ImportClause = 240, - NamespaceImport = 241, - NamedImports = 242, - ImportSpecifier = 243, - ExportAssignment = 244, - ExportDeclaration = 245, - NamedExports = 246, - ExportSpecifier = 247, - MissingDeclaration = 248, - ExternalModuleReference = 249, - JsxElement = 250, - JsxSelfClosingElement = 251, - JsxOpeningElement = 252, - JsxClosingElement = 253, - JsxFragment = 254, - JsxOpeningFragment = 255, - JsxClosingFragment = 256, - JsxAttribute = 257, - JsxAttributes = 258, - JsxSpreadAttribute = 259, - JsxExpression = 260, - CaseClause = 261, - DefaultClause = 262, - HeritageClause = 263, - CatchClause = 264, - PropertyAssignment = 265, - ShorthandPropertyAssignment = 266, - SpreadAssignment = 267, - EnumMember = 268, - SourceFile = 269, - Bundle = 270, - JSDocTypeExpression = 271, - JSDocAllType = 272, - JSDocUnknownType = 273, - JSDocNullableType = 274, - JSDocNonNullableType = 275, - JSDocOptionalType = 276, - JSDocFunctionType = 277, - JSDocVariadicType = 278, - JSDocComment = 279, - JSDocTypeLiteral = 280, - JSDocTag = 281, - JSDocAugmentsTag = 282, - JSDocClassTag = 283, - JSDocParameterTag = 284, - JSDocReturnTag = 285, - JSDocTypeTag = 286, - JSDocTemplateTag = 287, - JSDocTypedefTag = 288, - JSDocPropertyTag = 289, - SyntaxList = 290, - NotEmittedStatement = 291, - PartiallyEmittedExpression = 292, - CommaListExpression = 293, - MergeDeclarationMarker = 294, - EndOfDeclarationMarker = 295, - Count = 296, + 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, @@ -365,15 +368,15 @@ declare namespace ts { FirstReservedWord = 72, LastReservedWord = 107, FirstKeyword = 72, - LastKeyword = 143, + LastKeyword = 144, FirstFutureReservedWord = 108, LastFutureReservedWord = 116, - FirstTypeNode = 159, - LastTypeNode = 174, + FirstTypeNode = 160, + LastTypeNode = 177, FirstPunctuation = 17, LastPunctuation = 70, FirstToken = 0, - LastToken = 143, + LastToken = 144, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -382,11 +385,11 @@ declare namespace ts { LastTemplateToken = 16, FirstBinaryOperator = 27, LastBinaryOperator = 70, - FirstNode = 144, - FirstJSDocNode = 271, - LastJSDocNode = 289, - FirstJSDocTagNode = 281, - LastJSDocTagNode = 289, + FirstNode = 145, + FirstJSDocNode = 274, + LastJSDocNode = 292, + FirstJSDocTagNode = 284, + LastJSDocTagNode = 292, } enum NodeFlags { None = 0, @@ -517,7 +520,7 @@ declare namespace ts { } interface TypeParameterDeclaration extends NamedDeclaration { kind: SyntaxKind.TypeParameter; - parent?: DeclarationWithTypeParameters; + parent?: DeclarationWithTypeParameters | InferTypeNode; name: Identifier; constraint?: TypeNode; default?: TypeNode; @@ -734,6 +737,17 @@ declare namespace ts { kind: SyntaxKind.IntersectionType; types: NodeArray; } + interface ConditionalTypeNode extends TypeNode { + kind: SyntaxKind.ConditionalType; + checkType: TypeNode; + extendsType: TypeNode; + trueType: TypeNode; + falseType: TypeNode; + } + interface InferTypeNode extends TypeNode { + kind: SyntaxKind.InferType; + typeParameter: TypeParameterDeclaration; + } interface ParenthesizedTypeNode extends TypeNode { kind: SyntaxKind.ParenthesizedType; type: TypeNode; @@ -2044,8 +2058,9 @@ declare namespace ts { Intersection = 262144, Index = 524288, IndexedAccess = 1048576, - NonPrimitive = 33554432, - MarkerType = 134217728, + Conditional = 2097152, + Substitution = 4194304, + NonPrimitive = 134217728, Literal = 224, Unit = 13536, StringOrNumberLiteral = 96, @@ -2057,10 +2072,13 @@ declare namespace ts { ESSymbolLike = 1536, UnionOrIntersection = 393216, StructuredType = 458752, - StructuredOrTypeVariable = 2064384, TypeVariable = 1081344, - Narrowable = 35620607, - NotUnionOrUnit = 33620481, + InstantiableNonPrimitive = 7372800, + InstantiablePrimitive = 524288, + Instantiable = 7897088, + StructuredOrInstantiable = 8355840, + Narrowable = 142575359, + NotUnionOrUnit = 134283777, } type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; interface Type { @@ -2099,6 +2117,8 @@ declare namespace ts { ObjectLiteralPatternWithComputedProperties = 512, ContainsSpread = 1024, ReverseMapped = 2048, + JsxAttributes = 4096, + MarkerType = 8192, ClassOrInterface = 3, } interface ObjectType extends Type { @@ -2147,17 +2167,27 @@ declare namespace ts { elementType: Type; finalArrayType?: Type; } - interface TypeVariable extends Type { + interface InstantiableType extends Type { } - interface TypeParameter extends TypeVariable { + interface TypeParameter extends InstantiableType { } - interface IndexedAccessType extends TypeVariable { + interface IndexedAccessType extends InstantiableType { objectType: Type; indexType: Type; constraint?: Type; } - interface IndexType extends Type { - type: TypeVariable | UnionOrIntersectionType; + interface IndexType extends InstantiableType { + type: InstantiableType | UnionOrIntersectionType; + } + interface ConditionalType extends InstantiableType { + checkType: Type; + extendsType: Type; + trueType: Type; + falseType: Type; + } + interface SubstitutionType extends InstantiableType { + typeParameter: TypeParameter; + substitute: Type; } enum SignatureKind { Call = 0, @@ -2181,6 +2211,8 @@ declare namespace ts { NakedTypeVariable = 1, MappedType = 2, ReturnType = 4, + NoConstraints = 8, + AlwaysStrict = 16, } interface InferenceInfo { typeParameter: TypeParameter; @@ -3048,6 +3080,8 @@ declare namespace ts { function isTupleTypeNode(node: Node): node is TupleTypeNode; 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; @@ -3467,6 +3501,10 @@ declare namespace ts { function createIntersectionTypeNode(types: TypeNode[]): IntersectionTypeNode; function updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode; 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 f8ffc686008a2..65fcacaa5aa32 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -187,177 +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, - ParenthesizedType = 169, - ThisType = 170, - TypeOperator = 171, - IndexedAccessType = 172, - MappedType = 173, - LiteralType = 174, - ObjectBindingPattern = 175, - ArrayBindingPattern = 176, - BindingElement = 177, - ArrayLiteralExpression = 178, - ObjectLiteralExpression = 179, - PropertyAccessExpression = 180, - ElementAccessExpression = 181, - CallExpression = 182, - NewExpression = 183, - TaggedTemplateExpression = 184, - TypeAssertionExpression = 185, - ParenthesizedExpression = 186, - FunctionExpression = 187, - ArrowFunction = 188, - DeleteExpression = 189, - TypeOfExpression = 190, - VoidExpression = 191, - AwaitExpression = 192, - PrefixUnaryExpression = 193, - PostfixUnaryExpression = 194, - BinaryExpression = 195, - ConditionalExpression = 196, - TemplateExpression = 197, - YieldExpression = 198, - SpreadElement = 199, - ClassExpression = 200, - OmittedExpression = 201, - ExpressionWithTypeArguments = 202, - AsExpression = 203, - NonNullExpression = 204, - MetaProperty = 205, - TemplateSpan = 206, - SemicolonClassElement = 207, - Block = 208, - VariableStatement = 209, - EmptyStatement = 210, - ExpressionStatement = 211, - IfStatement = 212, - DoStatement = 213, - WhileStatement = 214, - ForStatement = 215, - ForInStatement = 216, - ForOfStatement = 217, - ContinueStatement = 218, - BreakStatement = 219, - ReturnStatement = 220, - WithStatement = 221, - SwitchStatement = 222, - LabeledStatement = 223, - ThrowStatement = 224, - TryStatement = 225, - DebuggerStatement = 226, - VariableDeclaration = 227, - VariableDeclarationList = 228, - FunctionDeclaration = 229, - ClassDeclaration = 230, - InterfaceDeclaration = 231, - TypeAliasDeclaration = 232, - EnumDeclaration = 233, - ModuleDeclaration = 234, - ModuleBlock = 235, - CaseBlock = 236, - NamespaceExportDeclaration = 237, - ImportEqualsDeclaration = 238, - ImportDeclaration = 239, - ImportClause = 240, - NamespaceImport = 241, - NamedImports = 242, - ImportSpecifier = 243, - ExportAssignment = 244, - ExportDeclaration = 245, - NamedExports = 246, - ExportSpecifier = 247, - MissingDeclaration = 248, - ExternalModuleReference = 249, - JsxElement = 250, - JsxSelfClosingElement = 251, - JsxOpeningElement = 252, - JsxClosingElement = 253, - JsxFragment = 254, - JsxOpeningFragment = 255, - JsxClosingFragment = 256, - JsxAttribute = 257, - JsxAttributes = 258, - JsxSpreadAttribute = 259, - JsxExpression = 260, - CaseClause = 261, - DefaultClause = 262, - HeritageClause = 263, - CatchClause = 264, - PropertyAssignment = 265, - ShorthandPropertyAssignment = 266, - SpreadAssignment = 267, - EnumMember = 268, - SourceFile = 269, - Bundle = 270, - JSDocTypeExpression = 271, - JSDocAllType = 272, - JSDocUnknownType = 273, - JSDocNullableType = 274, - JSDocNonNullableType = 275, - JSDocOptionalType = 276, - JSDocFunctionType = 277, - JSDocVariadicType = 278, - JSDocComment = 279, - JSDocTypeLiteral = 280, - JSDocTag = 281, - JSDocAugmentsTag = 282, - JSDocClassTag = 283, - JSDocParameterTag = 284, - JSDocReturnTag = 285, - JSDocTypeTag = 286, - JSDocTemplateTag = 287, - JSDocTypedefTag = 288, - JSDocPropertyTag = 289, - SyntaxList = 290, - NotEmittedStatement = 291, - PartiallyEmittedExpression = 292, - CommaListExpression = 293, - MergeDeclarationMarker = 294, - EndOfDeclarationMarker = 295, - Count = 296, + 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, @@ -365,15 +368,15 @@ declare namespace ts { FirstReservedWord = 72, LastReservedWord = 107, FirstKeyword = 72, - LastKeyword = 143, + LastKeyword = 144, FirstFutureReservedWord = 108, LastFutureReservedWord = 116, - FirstTypeNode = 159, - LastTypeNode = 174, + FirstTypeNode = 160, + LastTypeNode = 177, FirstPunctuation = 17, LastPunctuation = 70, FirstToken = 0, - LastToken = 143, + LastToken = 144, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -382,11 +385,11 @@ declare namespace ts { LastTemplateToken = 16, FirstBinaryOperator = 27, LastBinaryOperator = 70, - FirstNode = 144, - FirstJSDocNode = 271, - LastJSDocNode = 289, - FirstJSDocTagNode = 281, - LastJSDocTagNode = 289, + FirstNode = 145, + FirstJSDocNode = 274, + LastJSDocNode = 292, + FirstJSDocTagNode = 284, + LastJSDocTagNode = 292, } enum NodeFlags { None = 0, @@ -517,7 +520,7 @@ declare namespace ts { } interface TypeParameterDeclaration extends NamedDeclaration { kind: SyntaxKind.TypeParameter; - parent?: DeclarationWithTypeParameters; + parent?: DeclarationWithTypeParameters | InferTypeNode; name: Identifier; constraint?: TypeNode; default?: TypeNode; @@ -734,6 +737,17 @@ declare namespace ts { kind: SyntaxKind.IntersectionType; types: NodeArray; } + interface ConditionalTypeNode extends TypeNode { + kind: SyntaxKind.ConditionalType; + checkType: TypeNode; + extendsType: TypeNode; + trueType: TypeNode; + falseType: TypeNode; + } + interface InferTypeNode extends TypeNode { + kind: SyntaxKind.InferType; + typeParameter: TypeParameterDeclaration; + } interface ParenthesizedTypeNode extends TypeNode { kind: SyntaxKind.ParenthesizedType; type: TypeNode; @@ -2044,8 +2058,9 @@ declare namespace ts { Intersection = 262144, Index = 524288, IndexedAccess = 1048576, - NonPrimitive = 33554432, - MarkerType = 134217728, + Conditional = 2097152, + Substitution = 4194304, + NonPrimitive = 134217728, Literal = 224, Unit = 13536, StringOrNumberLiteral = 96, @@ -2057,10 +2072,13 @@ declare namespace ts { ESSymbolLike = 1536, UnionOrIntersection = 393216, StructuredType = 458752, - StructuredOrTypeVariable = 2064384, TypeVariable = 1081344, - Narrowable = 35620607, - NotUnionOrUnit = 33620481, + InstantiableNonPrimitive = 7372800, + InstantiablePrimitive = 524288, + Instantiable = 7897088, + StructuredOrInstantiable = 8355840, + Narrowable = 142575359, + NotUnionOrUnit = 134283777, } type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; interface Type { @@ -2099,6 +2117,8 @@ declare namespace ts { ObjectLiteralPatternWithComputedProperties = 512, ContainsSpread = 1024, ReverseMapped = 2048, + JsxAttributes = 4096, + MarkerType = 8192, ClassOrInterface = 3, } interface ObjectType extends Type { @@ -2147,17 +2167,27 @@ declare namespace ts { elementType: Type; finalArrayType?: Type; } - interface TypeVariable extends Type { + interface InstantiableType extends Type { } - interface TypeParameter extends TypeVariable { + interface TypeParameter extends InstantiableType { } - interface IndexedAccessType extends TypeVariable { + interface IndexedAccessType extends InstantiableType { objectType: Type; indexType: Type; constraint?: Type; } - interface IndexType extends Type { - type: TypeVariable | UnionOrIntersectionType; + interface IndexType extends InstantiableType { + type: InstantiableType | UnionOrIntersectionType; + } + interface ConditionalType extends InstantiableType { + checkType: Type; + extendsType: Type; + trueType: Type; + falseType: Type; + } + interface SubstitutionType extends InstantiableType { + typeParameter: TypeParameter; + substitute: Type; } enum SignatureKind { Call = 0, @@ -2181,6 +2211,8 @@ declare namespace ts { NakedTypeVariable = 1, MappedType = 2, ReturnType = 4, + NoConstraints = 8, + AlwaysStrict = 16, } interface InferenceInfo { typeParameter: TypeParameter; @@ -3103,6 +3135,8 @@ declare namespace ts { function isTupleTypeNode(node: Node): node is TupleTypeNode; 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; @@ -3414,6 +3448,10 @@ declare namespace ts { function createIntersectionTypeNode(types: TypeNode[]): IntersectionTypeNode; function updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode; 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 new file mode 100644 index 0000000000000..8016c4449d3e4 --- /dev/null +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -0,0 +1,341 @@ +tests/cases/conformance/types/conditional/conditionalTypes1.ts(16,5): error TS2322: Type 'T' is not assignable to type 'Diff'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(21,5): error TS2322: Type 'T' is not assignable to type 'Diff'. + Type 'string | undefined' is not assignable to type 'Diff'. + Type 'undefined' is not assignable to type 'Diff'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(22,9): error TS2322: Type 'T' is not assignable to type 'string'. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(28,5): error TS2322: Type 'Partial[keyof T]' is not assignable to type 'Diff[keyof T], null | undefined>'. + Type 'T[keyof T] | undefined' is not assignable to type 'Diff[keyof T], null | undefined>'. + Type 'undefined' is not assignable to type 'Diff[keyof T], null | undefined>'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(100,5): error TS2322: Type 'Pick' is not assignable to type 'T'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(101,5): error TS2322: Type 'Pick' is not assignable to type 'T'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(103,5): error TS2322: Type 'Pick' is not assignable to type 'Pick'. + Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. + Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. + Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(105,5): error TS2322: Type 'Pick' is not assignable to type 'Pick'. + Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. + Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. + Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(111,5): error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(112,5): error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. + Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. + Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. + Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(113,5): error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(114,5): error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. + Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. + Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. + Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(131,10): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(132,5): error TS2542: Index signature in type 'DeepReadonlyArray' only permits reading. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(133,22): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(134,10): error TS2339: Property 'updatePart' does not exist on type 'DeepReadonlyObject'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(156,5): error TS2322: Type 'ZeroOf' is not assignable to type 'T'. + Type '0 | (T extends string ? "" : false)' is not assignable to type 'T'. + Type '0' is not assignable to type 'T'. + Type '"" | 0' is not assignable to type 'T'. + Type '""' is not assignable to type 'T'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(157,5): error TS2322: Type 'T' is not assignable to type 'ZeroOf'. + Type 'string | number' is not assignable to type 'ZeroOf'. + Type 'string' is not assignable to type 'ZeroOf'. + + +==== tests/cases/conformance/types/conditional/conditionalTypes1.ts (18 errors) ==== + type Diff = T extends U ? never : T; + type Filter = T extends U ? T : never; + type NonNullable = Diff; + + type T00 = Diff<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "b" | "d" + type T01 = Filter<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "a" | "c" + + type T02 = Diff void), Function>; // string | number + type T03 = Filter void), Function>; // () => void + + type T04 = NonNullable; // string | number + type T05 = NonNullable<(() => string) | string[] | null | undefined>; // (() => string) | string[] + + function f1(x: T, y: NonNullable) { + x = y; + y = x; // Error + ~ +!!! error TS2322: Type 'T' is not assignable to type 'Diff'. + } + + function f2(x: T, y: NonNullable) { + x = y; + y = x; // Error + ~ +!!! error TS2322: Type 'T' is not assignable to type 'Diff'. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'Diff'. +!!! error TS2322: Type 'undefined' is not assignable to type 'Diff'. + let s1: string = x; // Error + ~~ +!!! error TS2322: Type 'T' is not assignable to type 'string'. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + let s2: string = y; + } + + function f3(x: Partial[keyof T], y: NonNullable[keyof T]>) { + x = y; + y = x; // Error + ~ +!!! error TS2322: Type 'Partial[keyof T]' is not assignable to type 'Diff[keyof T], null | undefined>'. +!!! error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'Diff[keyof T], null | undefined>'. +!!! error TS2322: Type 'undefined' is not assignable to type 'Diff[keyof T], null | undefined>'. + } + + type Options = { k: "a", a: number } | { k: "b", b: string } | { k: "c", c: boolean }; + + type T10 = Diff; // { k: "c", c: boolean } + type T11 = Filter; // { k: "a", a: number } | { k: "b", b: string } + + type T12 = Diff; // { k: "c", c: boolean } + type T13 = Filter; // { k: "a", a: number } | { k: "b", b: string } + + type T14 = Diff; // Options + type T15 = Filter; // never + + declare function f4(p: K): Filter; + let x0 = f4("a"); // { k: "a", a: number } + + type OptionsOfKind = Filter; + + type T16 = OptionsOfKind<"a" | "b">; // { k: "a", a: number } | { k: "b", b: string } + + type Select = Filter; + + type T17 = Select; // // { k: "a", a: number } | { k: "b", b: string } + + type TypeName = + T extends string ? "string" : + T extends number ? "number" : + T extends boolean ? "boolean" : + T extends undefined ? "undefined" : + T extends Function ? "function" : + "object"; + + type T20 = TypeName void)>; // "string" | "function" + type T21 = TypeName; // "string" | "number" | "boolean" | "undefined" | "function" | "object" + type T22 = TypeName; // "string" | "number" | "boolean" | "undefined" | "function" | "object" + type T23 = TypeName<{}>; // "object" + + type KnockoutObservable = { object: T }; + type KnockoutObservableArray = { array: T }; + + type KnockedOut = T extends any[] ? KnockoutObservableArray : KnockoutObservable; + + type KnockedOutObj = { + [P in keyof T]: KnockedOut; + } + + interface Item { + id: number; + name: string; + subitems: string[]; + } + + type KOItem = KnockedOutObj; + + interface Part { + id: number; + name: string; + subparts: Part[]; + updatePart(newName: string): void; + } + + type FunctionPropertyNames = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T]; + type FunctionProperties = Pick>; + + type NonFunctionPropertyNames = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]; + type NonFunctionProperties = Pick>; + + type T30 = FunctionProperties; + type T31 = NonFunctionProperties; + + function f7(x: T, y: FunctionProperties, z: NonFunctionProperties) { + x = y; // Error + ~ +!!! error TS2322: Type 'Pick' is not assignable to type 'T'. + x = z; // Error + ~ +!!! error TS2322: Type 'Pick' is not assignable to type 'T'. + y = x; + y = z; // Error + ~ +!!! error TS2322: Type 'Pick' is not assignable to type 'Pick'. +!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. +!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. +!!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + z = x; + z = y; // Error + ~ +!!! error TS2322: Type 'Pick' is not assignable to type 'Pick'. +!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. +!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. +!!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + } + + function f8(x: keyof T, y: FunctionPropertyNames, z: NonFunctionPropertyNames) { + x = y; + x = z; + y = x; // Error + ~ +!!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + y = z; // Error + ~ +!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. +!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. +!!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. +!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + z = x; // Error + ~ +!!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + z = y; // Error + ~ +!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. +!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. +!!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. +!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + } + + type DeepReadonly = + T extends any[] ? DeepReadonlyArray : + T extends object ? DeepReadonlyObject : + T; + + interface DeepReadonlyArray extends ReadonlyArray> {} + + type DeepReadonlyObject = { + readonly [P in NonFunctionPropertyNames]: DeepReadonly; + }; + + function f10(part: DeepReadonly) { + let name: string = part.name; + let id: number = part.subparts[0].id; + part.id = part.id; // Error + ~~ +!!! error TS2540: Cannot assign to 'id' because it is a constant or a read-only property. + part.subparts[0] = part.subparts[0]; // Error + ~~~~~~~~~~~~~~~~ +!!! error TS2542: Index signature in type 'DeepReadonlyArray' only permits reading. + part.subparts[0].id = part.subparts[0].id; // Error + ~~ +!!! error TS2540: Cannot assign to 'id' because it is a constant or a read-only property. + part.updatePart("hello"); // Error + ~~~~~~~~~~ +!!! error TS2339: Property 'updatePart' does not exist on type 'DeepReadonlyObject'. + } + + type ZeroOf = T extends number ? 0 : T extends string ? "" : false; + + function zeroOf(value: T) { + return >(typeof value === "number" ? 0 : typeof value === "string" ? "" : false); + } + + function f20(n: number, b: boolean, x: number | boolean, y: T) { + zeroOf(5); // 0 + zeroOf("hello"); // "" + zeroOf(true); // false + zeroOf(n); // 0 + zeroOf(b); // False + zeroOf(x); // 0 | false + zeroOf(y); // ZeroOf + } + + function f21(x: T, y: ZeroOf) { + let z1: number | string = y; + let z2: 0 | "" = y; + x = y; // Error + ~ +!!! error TS2322: Type 'ZeroOf' is not assignable to type 'T'. +!!! error TS2322: Type '0 | (T extends string ? "" : false)' is not assignable to type 'T'. +!!! error TS2322: Type '0' is not assignable to type 'T'. +!!! error TS2322: Type '"" | 0' is not assignable to type 'T'. +!!! error TS2322: Type '""' is not assignable to type 'T'. + y = x; // Error + ~ +!!! error TS2322: Type 'T' is not assignable to type 'ZeroOf'. +!!! error TS2322: Type 'string | number' is not assignable to type 'ZeroOf'. +!!! error TS2322: Type 'string' is not assignable to type 'ZeroOf'. + } + + type Extends = T extends U ? true : false; + type If = C extends true ? T : F; + type Not = If; + type And = If; + type Or = If; + + type isString = Extends; + + type Q1 = isString; // false + type Q2 = isString<"abc">; // true + type Q3 = isString; // boolean + type Q4 = isString; // boolean + + type N1 = Not; // true + type N2 = Not; // false + type N3 = Not; // boolean + + type A1 = And; // false + type A2 = And; // false + type A3 = And; // false + type A4 = And; // true + type A5 = And; // false + type A6 = And; // false + type A7 = And; // boolean + type A8 = And; // boolean + type A9 = And; // boolean + + type O1 = Or; // false + type O2 = Or; // true + type O3 = Or; // true + type O4 = Or; // true + type O5 = Or; // boolean + 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 + \ No newline at end of file diff --git a/tests/baselines/reference/conditionalTypes1.js b/tests/baselines/reference/conditionalTypes1.js new file mode 100644 index 0000000000000..088181b3b1241 --- /dev/null +++ b/tests/baselines/reference/conditionalTypes1.js @@ -0,0 +1,407 @@ +//// [conditionalTypes1.ts] +type Diff = T extends U ? never : T; +type Filter = T extends U ? T : never; +type NonNullable = Diff; + +type T00 = Diff<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "b" | "d" +type T01 = Filter<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "a" | "c" + +type T02 = Diff void), Function>; // string | number +type T03 = Filter void), Function>; // () => void + +type T04 = NonNullable; // string | number +type T05 = NonNullable<(() => string) | string[] | null | undefined>; // (() => string) | string[] + +function f1(x: T, y: NonNullable) { + x = y; + y = x; // Error +} + +function f2(x: T, y: NonNullable) { + x = y; + y = x; // Error + let s1: string = x; // Error + let s2: string = y; +} + +function f3(x: Partial[keyof T], y: NonNullable[keyof T]>) { + x = y; + y = x; // Error +} + +type Options = { k: "a", a: number } | { k: "b", b: string } | { k: "c", c: boolean }; + +type T10 = Diff; // { k: "c", c: boolean } +type T11 = Filter; // { k: "a", a: number } | { k: "b", b: string } + +type T12 = Diff; // { k: "c", c: boolean } +type T13 = Filter; // { k: "a", a: number } | { k: "b", b: string } + +type T14 = Diff; // Options +type T15 = Filter; // never + +declare function f4(p: K): Filter; +let x0 = f4("a"); // { k: "a", a: number } + +type OptionsOfKind = Filter; + +type T16 = OptionsOfKind<"a" | "b">; // { k: "a", a: number } | { k: "b", b: string } + +type Select = Filter; + +type T17 = Select; // // { k: "a", a: number } | { k: "b", b: string } + +type TypeName = + T extends string ? "string" : + T extends number ? "number" : + T extends boolean ? "boolean" : + T extends undefined ? "undefined" : + T extends Function ? "function" : + "object"; + +type T20 = TypeName void)>; // "string" | "function" +type T21 = TypeName; // "string" | "number" | "boolean" | "undefined" | "function" | "object" +type T22 = TypeName; // "string" | "number" | "boolean" | "undefined" | "function" | "object" +type T23 = TypeName<{}>; // "object" + +type KnockoutObservable = { object: T }; +type KnockoutObservableArray = { array: T }; + +type KnockedOut = T extends any[] ? KnockoutObservableArray : KnockoutObservable; + +type KnockedOutObj = { + [P in keyof T]: KnockedOut; +} + +interface Item { + id: number; + name: string; + subitems: string[]; +} + +type KOItem = KnockedOutObj; + +interface Part { + id: number; + name: string; + subparts: Part[]; + updatePart(newName: string): void; +} + +type FunctionPropertyNames = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T]; +type FunctionProperties = Pick>; + +type NonFunctionPropertyNames = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]; +type NonFunctionProperties = Pick>; + +type T30 = FunctionProperties; +type T31 = NonFunctionProperties; + +function f7(x: T, y: FunctionProperties, z: NonFunctionProperties) { + x = y; // Error + x = z; // Error + y = x; + y = z; // Error + z = x; + z = y; // Error +} + +function f8(x: keyof T, y: FunctionPropertyNames, z: NonFunctionPropertyNames) { + x = y; + x = z; + y = x; // Error + y = z; // Error + z = x; // Error + z = y; // Error +} + +type DeepReadonly = + T extends any[] ? DeepReadonlyArray : + T extends object ? DeepReadonlyObject : + T; + +interface DeepReadonlyArray extends ReadonlyArray> {} + +type DeepReadonlyObject = { + readonly [P in NonFunctionPropertyNames]: DeepReadonly; +}; + +function f10(part: DeepReadonly) { + let name: string = part.name; + let id: number = part.subparts[0].id; + part.id = part.id; // Error + part.subparts[0] = part.subparts[0]; // Error + part.subparts[0].id = part.subparts[0].id; // Error + part.updatePart("hello"); // Error +} + +type ZeroOf = T extends number ? 0 : T extends string ? "" : false; + +function zeroOf(value: T) { + return >(typeof value === "number" ? 0 : typeof value === "string" ? "" : false); +} + +function f20(n: number, b: boolean, x: number | boolean, y: T) { + zeroOf(5); // 0 + zeroOf("hello"); // "" + zeroOf(true); // false + zeroOf(n); // 0 + zeroOf(b); // False + zeroOf(x); // 0 | false + zeroOf(y); // ZeroOf +} + +function f21(x: T, y: ZeroOf) { + let z1: number | string = y; + let z2: 0 | "" = y; + x = y; // Error + y = x; // Error +} + +type Extends = T extends U ? true : false; +type If = C extends true ? T : F; +type Not = If; +type And = If; +type Or = If; + +type isString = Extends; + +type Q1 = isString; // false +type Q2 = isString<"abc">; // true +type Q3 = isString; // boolean +type Q4 = isString; // boolean + +type N1 = Not; // true +type N2 = Not; // false +type N3 = Not; // boolean + +type A1 = And; // false +type A2 = And; // false +type A3 = And; // false +type A4 = And; // true +type A5 = And; // false +type A6 = And; // false +type A7 = And; // boolean +type A8 = And; // boolean +type A9 = And; // boolean + +type O1 = Or; // false +type O2 = Or; // true +type O3 = Or; // true +type O4 = Or; // true +type O5 = Or; // boolean +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] +"use strict"; +function f1(x, y) { + x = y; + y = x; // Error +} +function f2(x, y) { + x = y; + y = x; // Error + var s1 = x; // Error + var s2 = y; +} +function f3(x, y) { + x = y; + y = x; // Error +} +var x0 = f4("a"); // { k: "a", a: number } +function f7(x, y, z) { + x = y; // Error + x = z; // Error + y = x; + y = z; // Error + z = x; + z = y; // Error +} +function f8(x, y, z) { + x = y; + x = z; + y = x; // Error + y = z; // Error + z = x; // Error + z = y; // Error +} +function f10(part) { + var name = part.name; + var id = part.subparts[0].id; + part.id = part.id; // Error + part.subparts[0] = part.subparts[0]; // Error + part.subparts[0].id = part.subparts[0].id; // Error + part.updatePart("hello"); // Error +} +function zeroOf(value) { + return (typeof value === "number" ? 0 : typeof value === "string" ? "" : false); +} +function f20(n, b, x, y) { + zeroOf(5); // 0 + zeroOf("hello"); // "" + zeroOf(true); // false + zeroOf(n); // 0 + zeroOf(b); // False + zeroOf(x); // 0 | false + zeroOf(y); // ZeroOf +} +function f21(x, y) { + var z1 = y; + var z2 = y; + x = y; // Error + y = x; // Error +} + + +//// [conditionalTypes1.d.ts] +declare type Diff = T extends U ? never : T; +declare type Filter = T extends U ? T : never; +declare type NonNullable = Diff; +declare type T00 = Diff<"a" | "b" | "c" | "d", "a" | "c" | "f">; +declare type T01 = Filter<"a" | "b" | "c" | "d", "a" | "c" | "f">; +declare type T02 = Diff void), Function>; +declare type T03 = Filter void), Function>; +declare type T04 = NonNullable; +declare type T05 = NonNullable<(() => string) | string[] | null | undefined>; +declare function f1(x: T, y: NonNullable): void; +declare function f2(x: T, y: NonNullable): void; +declare function f3(x: Partial[keyof T], y: NonNullable[keyof T]>): void; +declare type Options = { + k: "a"; + a: number; +} | { + k: "b"; + b: string; +} | { + k: "c"; + c: boolean; +}; +declare type T10 = Diff; +declare type T11 = Filter; +declare type T12 = Diff; +declare type T13 = Filter; +declare type T14 = Diff; +declare type T15 = Filter; +declare function f4(p: K): Filter; +declare let x0: { + k: "a"; + a: number; +}; +declare type OptionsOfKind = Filter; +declare type T16 = OptionsOfKind<"a" | "b">; +declare type Select = Filter; +declare type T17 = Select; +declare type TypeName = T extends string ? "string" : T extends number ? "number" : T extends boolean ? "boolean" : T extends undefined ? "undefined" : T extends Function ? "function" : "object"; +declare type T20 = TypeName void)>; +declare type T21 = TypeName; +declare type T22 = TypeName; +declare type T23 = TypeName<{}>; +declare type KnockoutObservable = { + object: T; +}; +declare type KnockoutObservableArray = { + array: T; +}; +declare type KnockedOut = T extends any[] ? KnockoutObservableArray : KnockoutObservable; +declare type KnockedOutObj = { + [P in keyof T]: KnockedOut; +}; +interface Item { + id: number; + name: string; + subitems: string[]; +} +declare type KOItem = KnockedOutObj; +interface Part { + id: number; + name: string; + subparts: Part[]; + updatePart(newName: string): void; +} +declare type FunctionPropertyNames = { + [K in keyof T]: T[K] extends Function ? K : never; +}[keyof T]; +declare type FunctionProperties = Pick>; +declare type NonFunctionPropertyNames = { + [K in keyof T]: T[K] extends Function ? never : K; +}[keyof T]; +declare type NonFunctionProperties = Pick>; +declare type T30 = FunctionProperties; +declare type T31 = NonFunctionProperties; +declare function f7(x: T, y: FunctionProperties, z: NonFunctionProperties): void; +declare function f8(x: keyof T, y: FunctionPropertyNames, z: NonFunctionPropertyNames): void; +declare type DeepReadonly = T extends any[] ? DeepReadonlyArray : T extends object ? DeepReadonlyObject : T; +interface DeepReadonlyArray extends ReadonlyArray> { +} +declare type DeepReadonlyObject = { + readonly [P in NonFunctionPropertyNames]: DeepReadonly; +}; +declare function f10(part: DeepReadonly): void; +declare type ZeroOf = T extends number ? 0 : T extends string ? "" : false; +declare function zeroOf(value: T): ZeroOf; +declare function f20(n: number, b: boolean, x: number | boolean, y: T): void; +declare function f21(x: T, y: ZeroOf): void; +declare type Extends = T extends U ? true : false; +declare type If = C extends true ? T : F; +declare type Not = If; +declare type And = If; +declare type Or = If; +declare type isString = Extends; +declare type Q1 = isString; +declare type Q2 = isString<"abc">; +declare type Q3 = isString; +declare type Q4 = isString; +declare type N1 = Not; +declare type N2 = Not; +declare type N3 = Not; +declare type A1 = And; +declare type A2 = And; +declare type A3 = And; +declare type A4 = And; +declare type A5 = And; +declare type A6 = And; +declare type A7 = And; +declare type A8 = And; +declare type A9 = And; +declare type O1 = Or; +declare type O2 = Or; +declare type O3 = Or; +declare type O4 = Or; +declare type O5 = Or; +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 new file mode 100644 index 0000000000000..ab0426f67d539 --- /dev/null +++ b/tests/baselines/reference/conditionalTypes1.symbols @@ -0,0 +1,762 @@ +=== tests/cases/conformance/types/conditional/conditionalTypes1.ts === +type Diff = T extends U ? never : T; +>Diff : Symbol(Diff, Decl(conditionalTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 0, 10)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 0, 12)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 0, 10)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 0, 12)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 0, 10)) + +type Filter = T extends U ? T : never; +>Filter : Symbol(Filter, Decl(conditionalTypes1.ts, 0, 42)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 1, 12)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 1, 14)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 1, 12)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 1, 14)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 1, 12)) + +type NonNullable = Diff; +>NonNullable : Symbol(NonNullable, Decl(conditionalTypes1.ts, 1, 44)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 2, 17)) +>Diff : Symbol(Diff, Decl(conditionalTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 2, 17)) + +type T00 = Diff<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "b" | "d" +>T00 : Symbol(T00, Decl(conditionalTypes1.ts, 2, 48)) +>Diff : Symbol(Diff, Decl(conditionalTypes1.ts, 0, 0)) + +type T01 = Filter<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "a" | "c" +>T01 : Symbol(T01, Decl(conditionalTypes1.ts, 4, 56)) +>Filter : Symbol(Filter, Decl(conditionalTypes1.ts, 0, 42)) + +type T02 = Diff void), Function>; // string | number +>T02 : Symbol(T02, Decl(conditionalTypes1.ts, 5, 58)) +>Diff : Symbol(Diff, Decl(conditionalTypes1.ts, 0, 0)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +type T03 = Filter void), Function>; // () => void +>T03 : Symbol(T03, Decl(conditionalTypes1.ts, 7, 58)) +>Filter : Symbol(Filter, Decl(conditionalTypes1.ts, 0, 42)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +type T04 = NonNullable; // string | number +>T04 : Symbol(T04, Decl(conditionalTypes1.ts, 8, 60)) +>NonNullable : Symbol(NonNullable, Decl(conditionalTypes1.ts, 1, 44)) + +type T05 = NonNullable<(() => string) | string[] | null | undefined>; // (() => string) | string[] +>T05 : Symbol(T05, Decl(conditionalTypes1.ts, 10, 52)) +>NonNullable : Symbol(NonNullable, Decl(conditionalTypes1.ts, 1, 44)) + +function f1(x: T, y: NonNullable) { +>f1 : Symbol(f1, Decl(conditionalTypes1.ts, 11, 69)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 13, 12)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 13, 15)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 13, 12)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 13, 20)) +>NonNullable : Symbol(NonNullable, Decl(conditionalTypes1.ts, 1, 44)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 13, 12)) + + x = y; +>x : Symbol(x, Decl(conditionalTypes1.ts, 13, 15)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 13, 20)) + + y = x; // Error +>y : Symbol(y, Decl(conditionalTypes1.ts, 13, 20)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 13, 15)) +} + +function f2(x: T, y: NonNullable) { +>f2 : Symbol(f2, Decl(conditionalTypes1.ts, 16, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 18, 12)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 18, 42)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 18, 12)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 18, 47)) +>NonNullable : Symbol(NonNullable, Decl(conditionalTypes1.ts, 1, 44)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 18, 12)) + + x = y; +>x : Symbol(x, Decl(conditionalTypes1.ts, 18, 42)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 18, 47)) + + y = x; // Error +>y : Symbol(y, Decl(conditionalTypes1.ts, 18, 47)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 18, 42)) + + let s1: string = x; // Error +>s1 : Symbol(s1, Decl(conditionalTypes1.ts, 21, 7)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 18, 42)) + + let s2: string = y; +>s2 : Symbol(s2, Decl(conditionalTypes1.ts, 22, 7)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 18, 47)) +} + +function f3(x: Partial[keyof T], y: NonNullable[keyof T]>) { +>f3 : Symbol(f3, Decl(conditionalTypes1.ts, 23, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 25, 12)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 25, 15)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 25, 12)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 25, 12)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 25, 38)) +>NonNullable : Symbol(NonNullable, Decl(conditionalTypes1.ts, 1, 44)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 25, 12)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 25, 12)) + + x = y; +>x : Symbol(x, Decl(conditionalTypes1.ts, 25, 15)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 25, 38)) + + y = x; // Error +>y : Symbol(y, Decl(conditionalTypes1.ts, 25, 38)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 25, 15)) +} + +type Options = { k: "a", a: number } | { k: "b", b: string } | { k: "c", c: boolean }; +>Options : Symbol(Options, Decl(conditionalTypes1.ts, 28, 1)) +>k : Symbol(k, Decl(conditionalTypes1.ts, 30, 16)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 30, 24)) +>k : Symbol(k, Decl(conditionalTypes1.ts, 30, 40)) +>b : Symbol(b, Decl(conditionalTypes1.ts, 30, 48)) +>k : Symbol(k, Decl(conditionalTypes1.ts, 30, 64)) +>c : Symbol(c, Decl(conditionalTypes1.ts, 30, 72)) + +type T10 = Diff; // { k: "c", c: boolean } +>T10 : Symbol(T10, Decl(conditionalTypes1.ts, 30, 86)) +>Diff : Symbol(Diff, Decl(conditionalTypes1.ts, 0, 0)) +>Options : Symbol(Options, Decl(conditionalTypes1.ts, 28, 1)) +>k : Symbol(k, Decl(conditionalTypes1.ts, 32, 26)) + +type T11 = Filter; // { k: "a", a: number } | { k: "b", b: string } +>T11 : Symbol(T11, Decl(conditionalTypes1.ts, 32, 43)) +>Filter : Symbol(Filter, Decl(conditionalTypes1.ts, 0, 42)) +>Options : Symbol(Options, Decl(conditionalTypes1.ts, 28, 1)) +>k : Symbol(k, Decl(conditionalTypes1.ts, 33, 28)) + +type T12 = Diff; // { k: "c", c: boolean } +>T12 : Symbol(T12, Decl(conditionalTypes1.ts, 33, 45)) +>Diff : Symbol(Diff, Decl(conditionalTypes1.ts, 0, 0)) +>Options : Symbol(Options, Decl(conditionalTypes1.ts, 28, 1)) +>k : Symbol(k, Decl(conditionalTypes1.ts, 35, 26)) +>k : Symbol(k, Decl(conditionalTypes1.ts, 35, 39)) + +type T13 = Filter; // { k: "a", a: number } | { k: "b", b: string } +>T13 : Symbol(T13, Decl(conditionalTypes1.ts, 35, 50)) +>Filter : Symbol(Filter, Decl(conditionalTypes1.ts, 0, 42)) +>Options : Symbol(Options, Decl(conditionalTypes1.ts, 28, 1)) +>k : Symbol(k, Decl(conditionalTypes1.ts, 36, 28)) +>k : Symbol(k, Decl(conditionalTypes1.ts, 36, 41)) + +type T14 = Diff; // Options +>T14 : Symbol(T14, Decl(conditionalTypes1.ts, 36, 52)) +>Diff : Symbol(Diff, Decl(conditionalTypes1.ts, 0, 0)) +>Options : Symbol(Options, Decl(conditionalTypes1.ts, 28, 1)) +>q : Symbol(q, Decl(conditionalTypes1.ts, 38, 26)) + +type T15 = Filter; // never +>T15 : Symbol(T15, Decl(conditionalTypes1.ts, 38, 37)) +>Filter : Symbol(Filter, Decl(conditionalTypes1.ts, 0, 42)) +>Options : Symbol(Options, Decl(conditionalTypes1.ts, 28, 1)) +>q : Symbol(q, Decl(conditionalTypes1.ts, 39, 28)) + +declare function f4(p: K): Filter; +>f4 : Symbol(f4, Decl(conditionalTypes1.ts, 39, 39)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 41, 20)) +>Options : Symbol(Options, Decl(conditionalTypes1.ts, 28, 1)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 41, 38)) +>p : Symbol(p, Decl(conditionalTypes1.ts, 41, 57)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 41, 38)) +>Filter : Symbol(Filter, Decl(conditionalTypes1.ts, 0, 42)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 41, 20)) +>k : Symbol(k, Decl(conditionalTypes1.ts, 41, 75)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 41, 38)) + +let x0 = f4("a"); // { k: "a", a: number } +>x0 : Symbol(x0, Decl(conditionalTypes1.ts, 42, 3)) +>f4 : Symbol(f4, Decl(conditionalTypes1.ts, 39, 39)) + +type OptionsOfKind = Filter; +>OptionsOfKind : Symbol(OptionsOfKind, Decl(conditionalTypes1.ts, 42, 17)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 44, 19)) +>Options : Symbol(Options, Decl(conditionalTypes1.ts, 28, 1)) +>Filter : Symbol(Filter, Decl(conditionalTypes1.ts, 0, 42)) +>Options : Symbol(Options, Decl(conditionalTypes1.ts, 28, 1)) +>k : Symbol(k, Decl(conditionalTypes1.ts, 44, 62)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 44, 19)) + +type T16 = OptionsOfKind<"a" | "b">; // { k: "a", a: number } | { k: "b", b: string } +>T16 : Symbol(T16, Decl(conditionalTypes1.ts, 44, 71)) +>OptionsOfKind : Symbol(OptionsOfKind, Decl(conditionalTypes1.ts, 42, 17)) + +type Select = Filter; +>Select : Symbol(Select, Decl(conditionalTypes1.ts, 46, 36)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 48, 12)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 48, 14)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 48, 12)) +>V : Symbol(V, Decl(conditionalTypes1.ts, 48, 33)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 48, 12)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 48, 14)) +>Filter : Symbol(Filter, Decl(conditionalTypes1.ts, 0, 42)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 48, 12)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 48, 65)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 48, 14)) +>V : Symbol(V, Decl(conditionalTypes1.ts, 48, 33)) + +type T17 = Select; // // { k: "a", a: number } | { k: "b", b: string } +>T17 : Symbol(T17, Decl(conditionalTypes1.ts, 48, 79)) +>Select : Symbol(Select, Decl(conditionalTypes1.ts, 46, 36)) +>Options : Symbol(Options, Decl(conditionalTypes1.ts, 28, 1)) + +type TypeName = +>TypeName : Symbol(TypeName, Decl(conditionalTypes1.ts, 50, 43)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 52, 14)) + + T extends string ? "string" : +>T : Symbol(T, Decl(conditionalTypes1.ts, 52, 14)) + + T extends number ? "number" : +>T : Symbol(T, Decl(conditionalTypes1.ts, 52, 14)) + + T extends boolean ? "boolean" : +>T : Symbol(T, Decl(conditionalTypes1.ts, 52, 14)) + + T extends undefined ? "undefined" : +>T : Symbol(T, Decl(conditionalTypes1.ts, 52, 14)) + + T extends Function ? "function" : +>T : Symbol(T, Decl(conditionalTypes1.ts, 52, 14)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + "object"; + +type T20 = TypeName void)>; // "string" | "function" +>T20 : Symbol(T20, Decl(conditionalTypes1.ts, 58, 13)) +>TypeName : Symbol(TypeName, Decl(conditionalTypes1.ts, 50, 43)) + +type T21 = TypeName; // "string" | "number" | "boolean" | "undefined" | "function" | "object" +>T21 : Symbol(T21, Decl(conditionalTypes1.ts, 60, 43)) +>TypeName : Symbol(TypeName, Decl(conditionalTypes1.ts, 50, 43)) + +type T22 = TypeName; // "string" | "number" | "boolean" | "undefined" | "function" | "object" +>T22 : Symbol(T22, Decl(conditionalTypes1.ts, 61, 25)) +>TypeName : Symbol(TypeName, Decl(conditionalTypes1.ts, 50, 43)) + +type T23 = TypeName<{}>; // "object" +>T23 : Symbol(T23, Decl(conditionalTypes1.ts, 62, 27)) +>TypeName : Symbol(TypeName, Decl(conditionalTypes1.ts, 50, 43)) + +type KnockoutObservable = { object: T }; +>KnockoutObservable : Symbol(KnockoutObservable, Decl(conditionalTypes1.ts, 63, 24)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 65, 24)) +>object : Symbol(object, Decl(conditionalTypes1.ts, 65, 30)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 65, 24)) + +type KnockoutObservableArray = { array: T }; +>KnockoutObservableArray : Symbol(KnockoutObservableArray, Decl(conditionalTypes1.ts, 65, 43)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 66, 29)) +>array : Symbol(array, Decl(conditionalTypes1.ts, 66, 35)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 66, 29)) + +type KnockedOut = T extends any[] ? KnockoutObservableArray : KnockoutObservable; +>KnockedOut : Symbol(KnockedOut, Decl(conditionalTypes1.ts, 66, 47)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 68, 16)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 68, 16)) +>KnockoutObservableArray : Symbol(KnockoutObservableArray, Decl(conditionalTypes1.ts, 65, 43)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 68, 16)) +>KnockoutObservable : Symbol(KnockoutObservable, Decl(conditionalTypes1.ts, 63, 24)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 68, 16)) + +type KnockedOutObj = { +>KnockedOutObj : Symbol(KnockedOutObj, Decl(conditionalTypes1.ts, 68, 98)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 70, 19)) + + [P in keyof T]: KnockedOut; +>P : Symbol(P, Decl(conditionalTypes1.ts, 71, 5)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 70, 19)) +>KnockedOut : Symbol(KnockedOut, Decl(conditionalTypes1.ts, 66, 47)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 70, 19)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 71, 5)) +} + +interface Item { +>Item : Symbol(Item, Decl(conditionalTypes1.ts, 72, 1)) + + id: number; +>id : Symbol(Item.id, Decl(conditionalTypes1.ts, 74, 16)) + + name: string; +>name : Symbol(Item.name, Decl(conditionalTypes1.ts, 75, 15)) + + subitems: string[]; +>subitems : Symbol(Item.subitems, Decl(conditionalTypes1.ts, 76, 17)) +} + +type KOItem = KnockedOutObj; +>KOItem : Symbol(KOItem, Decl(conditionalTypes1.ts, 78, 1)) +>KnockedOutObj : Symbol(KnockedOutObj, Decl(conditionalTypes1.ts, 68, 98)) +>Item : Symbol(Item, Decl(conditionalTypes1.ts, 72, 1)) + +interface Part { +>Part : Symbol(Part, Decl(conditionalTypes1.ts, 80, 34)) + + id: number; +>id : Symbol(Part.id, Decl(conditionalTypes1.ts, 82, 16)) + + name: string; +>name : Symbol(Part.name, Decl(conditionalTypes1.ts, 83, 15)) + + subparts: Part[]; +>subparts : Symbol(Part.subparts, Decl(conditionalTypes1.ts, 84, 17)) +>Part : Symbol(Part, Decl(conditionalTypes1.ts, 80, 34)) + + updatePart(newName: string): void; +>updatePart : Symbol(Part.updatePart, Decl(conditionalTypes1.ts, 85, 21)) +>newName : Symbol(newName, Decl(conditionalTypes1.ts, 86, 15)) +} + +type FunctionPropertyNames = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T]; +>FunctionPropertyNames : Symbol(FunctionPropertyNames, Decl(conditionalTypes1.ts, 87, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 89, 27)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 89, 35)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 89, 27)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 89, 27)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 89, 35)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 89, 35)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 89, 27)) + +type FunctionProperties = Pick>; +>FunctionProperties : Symbol(FunctionProperties, Decl(conditionalTypes1.ts, 89, 95)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 90, 24)) +>Pick : Symbol(Pick, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 90, 24)) +>FunctionPropertyNames : Symbol(FunctionPropertyNames, Decl(conditionalTypes1.ts, 87, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 90, 24)) + +type NonFunctionPropertyNames = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]; +>NonFunctionPropertyNames : Symbol(NonFunctionPropertyNames, Decl(conditionalTypes1.ts, 90, 63)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 92, 30)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 92, 38)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 92, 30)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 92, 30)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 92, 38)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 92, 38)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 92, 30)) + +type NonFunctionProperties = Pick>; +>NonFunctionProperties : Symbol(NonFunctionProperties, Decl(conditionalTypes1.ts, 92, 98)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 93, 27)) +>Pick : Symbol(Pick, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 93, 27)) +>NonFunctionPropertyNames : Symbol(NonFunctionPropertyNames, Decl(conditionalTypes1.ts, 90, 63)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 93, 27)) + +type T30 = FunctionProperties; +>T30 : Symbol(T30, Decl(conditionalTypes1.ts, 93, 69)) +>FunctionProperties : Symbol(FunctionProperties, Decl(conditionalTypes1.ts, 89, 95)) +>Part : Symbol(Part, Decl(conditionalTypes1.ts, 80, 34)) + +type T31 = NonFunctionProperties; +>T31 : Symbol(T31, Decl(conditionalTypes1.ts, 95, 36)) +>NonFunctionProperties : Symbol(NonFunctionProperties, Decl(conditionalTypes1.ts, 92, 98)) +>Part : Symbol(Part, Decl(conditionalTypes1.ts, 80, 34)) + +function f7(x: T, y: FunctionProperties, z: NonFunctionProperties) { +>f7 : Symbol(f7, Decl(conditionalTypes1.ts, 96, 39)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 98, 12)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 98, 15)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 98, 12)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 98, 20)) +>FunctionProperties : Symbol(FunctionProperties, Decl(conditionalTypes1.ts, 89, 95)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 98, 12)) +>z : Symbol(z, Decl(conditionalTypes1.ts, 98, 46)) +>NonFunctionProperties : Symbol(NonFunctionProperties, Decl(conditionalTypes1.ts, 92, 98)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 98, 12)) + + x = y; // Error +>x : Symbol(x, Decl(conditionalTypes1.ts, 98, 15)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 98, 20)) + + x = z; // Error +>x : Symbol(x, Decl(conditionalTypes1.ts, 98, 15)) +>z : Symbol(z, Decl(conditionalTypes1.ts, 98, 46)) + + y = x; +>y : Symbol(y, Decl(conditionalTypes1.ts, 98, 20)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 98, 15)) + + y = z; // Error +>y : Symbol(y, Decl(conditionalTypes1.ts, 98, 20)) +>z : Symbol(z, Decl(conditionalTypes1.ts, 98, 46)) + + z = x; +>z : Symbol(z, Decl(conditionalTypes1.ts, 98, 46)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 98, 15)) + + z = y; // Error +>z : Symbol(z, Decl(conditionalTypes1.ts, 98, 46)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 98, 20)) +} + +function f8(x: keyof T, y: FunctionPropertyNames, z: NonFunctionPropertyNames) { +>f8 : Symbol(f8, Decl(conditionalTypes1.ts, 105, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 107, 12)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 107, 15)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 107, 12)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 107, 26)) +>FunctionPropertyNames : Symbol(FunctionPropertyNames, Decl(conditionalTypes1.ts, 87, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 107, 12)) +>z : Symbol(z, Decl(conditionalTypes1.ts, 107, 55)) +>NonFunctionPropertyNames : Symbol(NonFunctionPropertyNames, Decl(conditionalTypes1.ts, 90, 63)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 107, 12)) + + x = y; +>x : Symbol(x, Decl(conditionalTypes1.ts, 107, 15)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 107, 26)) + + x = z; +>x : Symbol(x, Decl(conditionalTypes1.ts, 107, 15)) +>z : Symbol(z, Decl(conditionalTypes1.ts, 107, 55)) + + y = x; // Error +>y : Symbol(y, Decl(conditionalTypes1.ts, 107, 26)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 107, 15)) + + y = z; // Error +>y : Symbol(y, Decl(conditionalTypes1.ts, 107, 26)) +>z : Symbol(z, Decl(conditionalTypes1.ts, 107, 55)) + + z = x; // Error +>z : Symbol(z, Decl(conditionalTypes1.ts, 107, 55)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 107, 15)) + + z = y; // Error +>z : Symbol(z, Decl(conditionalTypes1.ts, 107, 55)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 107, 26)) +} + +type DeepReadonly = +>DeepReadonly : Symbol(DeepReadonly, Decl(conditionalTypes1.ts, 114, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 116, 18)) + + T extends any[] ? DeepReadonlyArray : +>T : Symbol(T, Decl(conditionalTypes1.ts, 116, 18)) +>DeepReadonlyArray : Symbol(DeepReadonlyArray, Decl(conditionalTypes1.ts, 119, 6)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 116, 18)) + + T extends object ? DeepReadonlyObject : +>T : Symbol(T, Decl(conditionalTypes1.ts, 116, 18)) +>DeepReadonlyObject : Symbol(DeepReadonlyObject, Decl(conditionalTypes1.ts, 121, 72)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 116, 18)) + + T; +>T : Symbol(T, Decl(conditionalTypes1.ts, 116, 18)) + +interface DeepReadonlyArray extends ReadonlyArray> {} +>DeepReadonlyArray : Symbol(DeepReadonlyArray, Decl(conditionalTypes1.ts, 119, 6)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 121, 28)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.d.ts, --, --)) +>DeepReadonly : Symbol(DeepReadonly, Decl(conditionalTypes1.ts, 114, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 121, 28)) + +type DeepReadonlyObject = { +>DeepReadonlyObject : Symbol(DeepReadonlyObject, Decl(conditionalTypes1.ts, 121, 72)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 123, 24)) + + readonly [P in NonFunctionPropertyNames]: DeepReadonly; +>P : Symbol(P, Decl(conditionalTypes1.ts, 124, 14)) +>NonFunctionPropertyNames : Symbol(NonFunctionPropertyNames, Decl(conditionalTypes1.ts, 90, 63)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 123, 24)) +>DeepReadonly : Symbol(DeepReadonly, Decl(conditionalTypes1.ts, 114, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 123, 24)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 124, 14)) + +}; + +function f10(part: DeepReadonly) { +>f10 : Symbol(f10, Decl(conditionalTypes1.ts, 125, 2)) +>part : Symbol(part, Decl(conditionalTypes1.ts, 127, 13)) +>DeepReadonly : Symbol(DeepReadonly, Decl(conditionalTypes1.ts, 114, 1)) +>Part : Symbol(Part, Decl(conditionalTypes1.ts, 80, 34)) + + let name: string = part.name; +>name : Symbol(name, Decl(conditionalTypes1.ts, 128, 7)) +>part.name : Symbol(name) +>part : Symbol(part, Decl(conditionalTypes1.ts, 127, 13)) +>name : Symbol(name) + + let id: number = part.subparts[0].id; +>id : Symbol(id, Decl(conditionalTypes1.ts, 129, 7)) +>part.subparts[0].id : Symbol(id) +>part.subparts : Symbol(subparts) +>part : Symbol(part, Decl(conditionalTypes1.ts, 127, 13)) +>subparts : Symbol(subparts) +>id : Symbol(id) + + part.id = part.id; // Error +>part.id : Symbol(id) +>part : Symbol(part, Decl(conditionalTypes1.ts, 127, 13)) +>id : Symbol(id) +>part.id : Symbol(id) +>part : Symbol(part, Decl(conditionalTypes1.ts, 127, 13)) +>id : Symbol(id) + + part.subparts[0] = part.subparts[0]; // Error +>part.subparts : Symbol(subparts) +>part : Symbol(part, Decl(conditionalTypes1.ts, 127, 13)) +>subparts : Symbol(subparts) +>part.subparts : Symbol(subparts) +>part : Symbol(part, Decl(conditionalTypes1.ts, 127, 13)) +>subparts : Symbol(subparts) + + part.subparts[0].id = part.subparts[0].id; // Error +>part.subparts[0].id : Symbol(id) +>part.subparts : Symbol(subparts) +>part : Symbol(part, Decl(conditionalTypes1.ts, 127, 13)) +>subparts : Symbol(subparts) +>id : Symbol(id) +>part.subparts[0].id : Symbol(id) +>part.subparts : Symbol(subparts) +>part : Symbol(part, Decl(conditionalTypes1.ts, 127, 13)) +>subparts : Symbol(subparts) +>id : Symbol(id) + + part.updatePart("hello"); // Error +>part : Symbol(part, Decl(conditionalTypes1.ts, 127, 13)) +} + +type ZeroOf = T extends number ? 0 : T extends string ? "" : false; +>ZeroOf : Symbol(ZeroOf, Decl(conditionalTypes1.ts, 134, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 136, 12)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 136, 12)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 136, 12)) + +function zeroOf(value: T) { +>zeroOf : Symbol(zeroOf, Decl(conditionalTypes1.ts, 136, 104)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 138, 16)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 138, 53)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 138, 16)) + + return >(typeof value === "number" ? 0 : typeof value === "string" ? "" : false); +>ZeroOf : Symbol(ZeroOf, Decl(conditionalTypes1.ts, 134, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 138, 16)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 138, 53)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 138, 53)) +} + +function f20(n: number, b: boolean, x: number | boolean, y: T) { +>f20 : Symbol(f20, Decl(conditionalTypes1.ts, 140, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 142, 13)) +>n : Symbol(n, Decl(conditionalTypes1.ts, 142, 31)) +>b : Symbol(b, Decl(conditionalTypes1.ts, 142, 41)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 142, 53)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 142, 74)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 142, 13)) + + zeroOf(5); // 0 +>zeroOf : Symbol(zeroOf, Decl(conditionalTypes1.ts, 136, 104)) + + zeroOf("hello"); // "" +>zeroOf : Symbol(zeroOf, Decl(conditionalTypes1.ts, 136, 104)) + + zeroOf(true); // false +>zeroOf : Symbol(zeroOf, Decl(conditionalTypes1.ts, 136, 104)) + + zeroOf(n); // 0 +>zeroOf : Symbol(zeroOf, Decl(conditionalTypes1.ts, 136, 104)) +>n : Symbol(n, Decl(conditionalTypes1.ts, 142, 31)) + + zeroOf(b); // False +>zeroOf : Symbol(zeroOf, Decl(conditionalTypes1.ts, 136, 104)) +>b : Symbol(b, Decl(conditionalTypes1.ts, 142, 41)) + + zeroOf(x); // 0 | false +>zeroOf : Symbol(zeroOf, Decl(conditionalTypes1.ts, 136, 104)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 142, 53)) + + zeroOf(y); // ZeroOf +>zeroOf : Symbol(zeroOf, Decl(conditionalTypes1.ts, 136, 104)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 142, 74)) +} + +function f21(x: T, y: ZeroOf) { +>f21 : Symbol(f21, Decl(conditionalTypes1.ts, 150, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 152, 13)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 152, 40)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 152, 13)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 152, 45)) +>ZeroOf : Symbol(ZeroOf, Decl(conditionalTypes1.ts, 134, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 152, 13)) + + let z1: number | string = y; +>z1 : Symbol(z1, Decl(conditionalTypes1.ts, 153, 7)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 152, 45)) + + let z2: 0 | "" = y; +>z2 : Symbol(z2, Decl(conditionalTypes1.ts, 154, 7)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 152, 45)) + + x = y; // Error +>x : Symbol(x, Decl(conditionalTypes1.ts, 152, 40)) +>y : Symbol(y, Decl(conditionalTypes1.ts, 152, 45)) + + y = x; // Error +>y : Symbol(y, Decl(conditionalTypes1.ts, 152, 45)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 152, 40)) +} + +type Extends = T extends U ? true : false; +>Extends : Symbol(Extends, Decl(conditionalTypes1.ts, 157, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 159, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 159, 15)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 159, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 159, 15)) + +type If = C extends true ? T : F; +>If : Symbol(If, Decl(conditionalTypes1.ts, 159, 48)) +>C : Symbol(C, Decl(conditionalTypes1.ts, 160, 8)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 160, 26)) +>F : Symbol(F, Decl(conditionalTypes1.ts, 160, 29)) +>C : Symbol(C, Decl(conditionalTypes1.ts, 160, 8)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 160, 26)) +>F : Symbol(F, Decl(conditionalTypes1.ts, 160, 29)) + +type Not = If; +>Not : Symbol(Not, Decl(conditionalTypes1.ts, 160, 58)) +>C : Symbol(C, Decl(conditionalTypes1.ts, 161, 9)) +>If : Symbol(If, Decl(conditionalTypes1.ts, 159, 48)) +>C : Symbol(C, Decl(conditionalTypes1.ts, 161, 9)) + +type And = If; +>And : Symbol(And, Decl(conditionalTypes1.ts, 161, 49)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 162, 9)) +>B : Symbol(B, Decl(conditionalTypes1.ts, 162, 27)) +>If : Symbol(If, Decl(conditionalTypes1.ts, 159, 48)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 162, 9)) +>B : Symbol(B, Decl(conditionalTypes1.ts, 162, 27)) + +type Or = If; +>Or : Symbol(Or, Decl(conditionalTypes1.ts, 162, 65)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 163, 8)) +>B : Symbol(B, Decl(conditionalTypes1.ts, 163, 26)) +>If : Symbol(If, Decl(conditionalTypes1.ts, 159, 48)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 163, 8)) +>B : Symbol(B, Decl(conditionalTypes1.ts, 163, 26)) + +type isString = Extends; +>isString : Symbol(isString, Decl(conditionalTypes1.ts, 163, 63)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 165, 14)) +>Extends : Symbol(Extends, Decl(conditionalTypes1.ts, 157, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 165, 14)) + +type Q1 = isString; // false +>Q1 : Symbol(Q1, Decl(conditionalTypes1.ts, 165, 38)) +>isString : Symbol(isString, Decl(conditionalTypes1.ts, 163, 63)) + +type Q2 = isString<"abc">; // true +>Q2 : Symbol(Q2, Decl(conditionalTypes1.ts, 167, 27)) +>isString : Symbol(isString, Decl(conditionalTypes1.ts, 163, 63)) + +type Q3 = isString; // boolean +>Q3 : Symbol(Q3, Decl(conditionalTypes1.ts, 168, 26)) +>isString : Symbol(isString, Decl(conditionalTypes1.ts, 163, 63)) + +type Q4 = isString; // boolean +>Q4 : Symbol(Q4, Decl(conditionalTypes1.ts, 169, 24)) +>isString : Symbol(isString, Decl(conditionalTypes1.ts, 163, 63)) + +type N1 = Not; // true +>N1 : Symbol(N1, Decl(conditionalTypes1.ts, 170, 26)) +>Not : Symbol(Not, Decl(conditionalTypes1.ts, 160, 58)) + +type N2 = Not; // false +>N2 : Symbol(N2, Decl(conditionalTypes1.ts, 172, 21)) +>Not : Symbol(Not, Decl(conditionalTypes1.ts, 160, 58)) + +type N3 = Not; // boolean +>N3 : Symbol(N3, Decl(conditionalTypes1.ts, 173, 20)) +>Not : Symbol(Not, Decl(conditionalTypes1.ts, 160, 58)) + +type A1 = And; // false +>A1 : Symbol(A1, Decl(conditionalTypes1.ts, 174, 23)) +>And : Symbol(And, Decl(conditionalTypes1.ts, 161, 49)) + +type A2 = And; // false +>A2 : Symbol(A2, Decl(conditionalTypes1.ts, 176, 28)) +>And : Symbol(And, Decl(conditionalTypes1.ts, 161, 49)) + +type A3 = And; // false +>A3 : Symbol(A3, Decl(conditionalTypes1.ts, 177, 27)) +>And : Symbol(And, Decl(conditionalTypes1.ts, 161, 49)) + +type A4 = And; // true +>A4 : Symbol(A4, Decl(conditionalTypes1.ts, 178, 27)) +>And : Symbol(And, Decl(conditionalTypes1.ts, 161, 49)) + +type A5 = And; // false +>A5 : Symbol(A5, Decl(conditionalTypes1.ts, 179, 26)) +>And : Symbol(And, Decl(conditionalTypes1.ts, 161, 49)) + +type A6 = And; // false +>A6 : Symbol(A6, Decl(conditionalTypes1.ts, 180, 30)) +>And : Symbol(And, Decl(conditionalTypes1.ts, 161, 49)) + +type A7 = And; // boolean +>A7 : Symbol(A7, Decl(conditionalTypes1.ts, 181, 30)) +>And : Symbol(And, Decl(conditionalTypes1.ts, 161, 49)) + +type A8 = And; // boolean +>A8 : Symbol(A8, Decl(conditionalTypes1.ts, 182, 29)) +>And : Symbol(And, Decl(conditionalTypes1.ts, 161, 49)) + +type A9 = And; // boolean +>A9 : Symbol(A9, Decl(conditionalTypes1.ts, 183, 29)) +>And : Symbol(And, Decl(conditionalTypes1.ts, 161, 49)) + +type O1 = Or; // false +>O1 : Symbol(O1, Decl(conditionalTypes1.ts, 184, 32)) +>Or : Symbol(Or, Decl(conditionalTypes1.ts, 162, 65)) + +type O2 = Or; // true +>O2 : Symbol(O2, Decl(conditionalTypes1.ts, 186, 27)) +>Or : Symbol(Or, Decl(conditionalTypes1.ts, 162, 65)) + +type O3 = Or; // true +>O3 : Symbol(O3, Decl(conditionalTypes1.ts, 187, 26)) +>Or : Symbol(Or, Decl(conditionalTypes1.ts, 162, 65)) + +type O4 = Or; // true +>O4 : Symbol(O4, Decl(conditionalTypes1.ts, 188, 26)) +>Or : Symbol(Or, Decl(conditionalTypes1.ts, 162, 65)) + +type O5 = Or; // boolean +>O5 : Symbol(O5, Decl(conditionalTypes1.ts, 189, 25)) +>Or : Symbol(Or, Decl(conditionalTypes1.ts, 162, 65)) + +type O6 = Or; // boolean +>O6 : Symbol(O6, Decl(conditionalTypes1.ts, 190, 29)) +>Or : Symbol(Or, Decl(conditionalTypes1.ts, 162, 65)) + +type O7 = Or; // true +>O7 : Symbol(O7, Decl(conditionalTypes1.ts, 191, 29)) +>Or : Symbol(Or, Decl(conditionalTypes1.ts, 162, 65)) + +type O8 = Or; // true +>O8 : Symbol(O8, Decl(conditionalTypes1.ts, 192, 28)) +>Or : Symbol(Or, Decl(conditionalTypes1.ts, 162, 65)) + +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 new file mode 100644 index 0000000000000..9fc72f368d5a6 --- /dev/null +++ b/tests/baselines/reference/conditionalTypes1.types @@ -0,0 +1,866 @@ +=== tests/cases/conformance/types/conditional/conditionalTypes1.ts === +type Diff = T extends U ? never : T; +>Diff : Diff +>T : T +>U : U +>T : T +>U : U +>T : T + +type Filter = T extends U ? T : never; +>Filter : Filter +>T : T +>U : U +>T : T +>U : U +>T : T + +type NonNullable = Diff; +>NonNullable : Diff +>T : T +>Diff : Diff +>T : T +>null : null + +type T00 = Diff<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "b" | "d" +>T00 : "b" | "d" +>Diff : Diff + +type T01 = Filter<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "a" | "c" +>T01 : "a" | "c" +>Filter : Filter + +type T02 = Diff void), Function>; // string | number +>T02 : string | number +>Diff : Diff +>Function : Function + +type T03 = Filter void), Function>; // () => void +>T03 : () => void +>Filter : Filter +>Function : Function + +type T04 = NonNullable; // string | number +>T04 : string | number +>NonNullable : Diff + +type T05 = NonNullable<(() => string) | string[] | null | undefined>; // (() => string) | string[] +>T05 : (() => string) | string[] +>NonNullable : Diff +>null : null + +function f1(x: T, y: NonNullable) { +>f1 : (x: T, y: Diff) => void +>T : T +>x : T +>T : T +>y : Diff +>NonNullable : Diff +>T : T + + x = y; +>x = y : Diff +>x : T +>y : Diff + + y = x; // Error +>y = x : T +>y : Diff +>x : T +} + +function f2(x: T, y: NonNullable) { +>f2 : (x: T, y: Diff) => void +>T : T +>x : T +>T : T +>y : Diff +>NonNullable : Diff +>T : T + + x = y; +>x = y : Diff +>x : T +>y : Diff + + y = x; // Error +>y = x : T +>y : Diff +>x : T + + let s1: string = x; // Error +>s1 : string +>x : T + + let s2: string = y; +>s2 : string +>y : Diff +} + +function f3(x: Partial[keyof T], y: NonNullable[keyof T]>) { +>f3 : (x: Partial[keyof T], y: Diff[keyof T], null | undefined>) => void +>T : T +>x : Partial[keyof T] +>Partial : Partial +>T : T +>T : T +>y : Diff[keyof T], null | undefined> +>NonNullable : Diff +>Partial : Partial +>T : T +>T : T + + x = y; +>x = y : Diff[keyof T], null | undefined> +>x : Partial[keyof T] +>y : Diff[keyof T], null | undefined> + + y = x; // Error +>y = x : Partial[keyof T] +>y : Diff[keyof T], null | undefined> +>x : Partial[keyof T] +} + +type Options = { k: "a", a: number } | { k: "b", b: string } | { k: "c", c: boolean }; +>Options : Options +>k : "a" +>a : number +>k : "b" +>b : string +>k : "c" +>c : boolean + +type T10 = Diff; // { k: "c", c: boolean } +>T10 : { k: "c"; c: boolean; } +>Diff : Diff +>Options : Options +>k : "a" | "b" + +type T11 = Filter; // { k: "a", a: number } | { k: "b", b: string } +>T11 : { k: "a"; a: number; } | { k: "b"; b: string; } +>Filter : Filter +>Options : Options +>k : "a" | "b" + +type T12 = Diff; // { k: "c", c: boolean } +>T12 : { k: "c"; c: boolean; } +>Diff : Diff +>Options : Options +>k : "a" +>k : "b" + +type T13 = Filter; // { k: "a", a: number } | { k: "b", b: string } +>T13 : { k: "a"; a: number; } | { k: "b"; b: string; } +>Filter : Filter +>Options : Options +>k : "a" +>k : "b" + +type T14 = Diff; // Options +>T14 : Options +>Diff : Diff +>Options : Options +>q : "a" + +type T15 = Filter; // never +>T15 : never +>Filter : Filter +>Options : Options +>q : "a" + +declare function f4(p: K): Filter; +>f4 : (p: K) => Filter +>T : T +>Options : Options +>K : K +>p : K +>K : K +>Filter : Filter +>T : T +>k : K +>K : K + +let x0 = f4("a"); // { k: "a", a: number } +>x0 : { k: "a"; a: number; } +>f4("a") : { k: "a"; a: number; } +>f4 : (p: K) => Filter +>"a" : "a" + +type OptionsOfKind = Filter; +>OptionsOfKind : Filter<{ k: "a"; a: number; }, { k: K; }> | Filter<{ k: "b"; b: string; }, { k: K; }> | Filter<{ k: "c"; c: boolean; }, { k: K; }> +>K : K +>Options : Options +>Filter : Filter +>Options : Options +>k : K +>K : K + +type T16 = OptionsOfKind<"a" | "b">; // { k: "a", a: number } | { k: "b", b: string } +>T16 : { k: "a"; a: number; } | { k: "b"; b: string; } +>OptionsOfKind : Filter<{ k: "a"; a: number; }, { k: K; }> | Filter<{ k: "b"; b: string; }, { k: K; }> | Filter<{ k: "c"; c: boolean; }, { k: K; }> + +type Select = Filter; +>Select : Filter +>T : T +>K : K +>T : T +>V : V +>T : T +>K : K +>Filter : Filter +>T : T +>P : P +>K : K +>V : V + +type T17 = Select; // // { k: "a", a: number } | { k: "b", b: string } +>T17 : { k: "a"; a: number; } | { k: "b"; b: string; } +>Select : Filter +>Options : Options + +type TypeName = +>TypeName : TypeName +>T : T + + T extends string ? "string" : +>T : T + + T extends number ? "number" : +>T : T + + T extends boolean ? "boolean" : +>T : T + + T extends undefined ? "undefined" : +>T : T + + T extends Function ? "function" : +>T : T +>Function : Function + + "object"; + +type T20 = TypeName void)>; // "string" | "function" +>T20 : "string" | "function" +>TypeName : TypeName + +type T21 = TypeName; // "string" | "number" | "boolean" | "undefined" | "function" | "object" +>T21 : "string" | "number" | "boolean" | "undefined" | "object" | "function" +>TypeName : TypeName + +type T22 = TypeName; // "string" | "number" | "boolean" | "undefined" | "function" | "object" +>T22 : "string" | "number" | "boolean" | "undefined" | "object" | "function" +>TypeName : TypeName + +type T23 = TypeName<{}>; // "object" +>T23 : "object" +>TypeName : TypeName + +type KnockoutObservable = { object: T }; +>KnockoutObservable : KnockoutObservable +>T : T +>object : T +>T : T + +type KnockoutObservableArray = { array: T }; +>KnockoutObservableArray : KnockoutObservableArray +>T : T +>array : T +>T : T + +type KnockedOut = T extends any[] ? KnockoutObservableArray : KnockoutObservable; +>KnockedOut : KnockedOut +>T : T +>T : T +>KnockoutObservableArray : KnockoutObservableArray +>T : T +>KnockoutObservable : KnockoutObservable +>T : T + +type KnockedOutObj = { +>KnockedOutObj : KnockedOutObj +>T : T + + [P in keyof T]: KnockedOut; +>P : P +>T : T +>KnockedOut : KnockedOut +>T : T +>P : P +} + +interface Item { +>Item : Item + + id: number; +>id : number + + name: string; +>name : string + + subitems: string[]; +>subitems : string[] +} + +type KOItem = KnockedOutObj; +>KOItem : KnockedOutObj +>KnockedOutObj : KnockedOutObj +>Item : Item + +interface Part { +>Part : Part + + id: number; +>id : number + + name: string; +>name : string + + subparts: Part[]; +>subparts : Part[] +>Part : Part + + updatePart(newName: string): void; +>updatePart : (newName: string) => void +>newName : string +} + +type FunctionPropertyNames = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T]; +>FunctionPropertyNames : { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T] +>T : T +>K : K +>T : T +>T : T +>K : K +>Function : Function +>K : K +>T : T + +type FunctionProperties = Pick>; +>FunctionProperties : Pick +>T : T +>Pick : Pick +>T : T +>FunctionPropertyNames : { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T] +>T : T + +type NonFunctionPropertyNames = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]; +>NonFunctionPropertyNames : { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T] +>T : T +>K : K +>T : T +>T : T +>K : K +>Function : Function +>K : K +>T : T + +type NonFunctionProperties = Pick>; +>NonFunctionProperties : Pick +>T : T +>Pick : Pick +>T : T +>NonFunctionPropertyNames : { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T] +>T : T + +type T30 = FunctionProperties; +>T30 : Pick +>FunctionProperties : Pick +>Part : Part + +type T31 = NonFunctionProperties; +>T31 : Pick +>NonFunctionProperties : Pick +>Part : Part + +function f7(x: T, y: FunctionProperties, z: NonFunctionProperties) { +>f7 : (x: T, y: Pick, z: Pick) => void +>T : T +>x : T +>T : T +>y : Pick +>FunctionProperties : Pick +>T : T +>z : Pick +>NonFunctionProperties : Pick +>T : T + + x = y; // Error +>x = y : Pick +>x : T +>y : Pick + + x = z; // Error +>x = z : Pick +>x : T +>z : Pick + + y = x; +>y = x : T +>y : Pick +>x : T + + y = z; // Error +>y = z : Pick +>y : Pick +>z : Pick + + z = x; +>z = x : T +>z : Pick +>x : T + + z = y; // Error +>z = y : Pick +>z : Pick +>y : Pick +} + +function f8(x: keyof T, y: FunctionPropertyNames, z: NonFunctionPropertyNames) { +>f8 : (x: keyof T, y: { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T], z: { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]) => void +>T : T +>x : keyof T +>T : T +>y : { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T] +>FunctionPropertyNames : { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T] +>T : T +>z : { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T] +>NonFunctionPropertyNames : { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T] +>T : T + + x = y; +>x = y : { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T] +>x : keyof T +>y : { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T] + + x = z; +>x = z : { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T] +>x : keyof T +>z : { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T] + + y = x; // Error +>y = x : keyof T +>y : { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T] +>x : keyof T + + y = z; // Error +>y = z : { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T] +>y : { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T] +>z : { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T] + + z = x; // Error +>z = x : keyof T +>z : { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T] +>x : keyof T + + z = y; // Error +>z = y : { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T] +>z : { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T] +>y : { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T] +} + +type DeepReadonly = +>DeepReadonly : DeepReadonly +>T : T + + T extends any[] ? DeepReadonlyArray : +>T : T +>DeepReadonlyArray : DeepReadonlyArray +>T : T + + T extends object ? DeepReadonlyObject : +>T : T +>DeepReadonlyObject : DeepReadonlyObject +>T : T + + T; +>T : T + +interface DeepReadonlyArray extends ReadonlyArray> {} +>DeepReadonlyArray : DeepReadonlyArray +>T : T +>ReadonlyArray : ReadonlyArray +>DeepReadonly : DeepReadonly +>T : T + +type DeepReadonlyObject = { +>DeepReadonlyObject : DeepReadonlyObject +>T : T + + readonly [P in NonFunctionPropertyNames]: DeepReadonly; +>P : P +>NonFunctionPropertyNames : { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T] +>T : T +>DeepReadonly : DeepReadonly +>T : T +>P : P + +}; + +function f10(part: DeepReadonly) { +>f10 : (part: DeepReadonlyObject) => void +>part : DeepReadonlyObject +>DeepReadonly : DeepReadonly +>Part : Part + + let name: string = part.name; +>name : string +>part.name : string +>part : DeepReadonlyObject +>name : string + + let id: number = part.subparts[0].id; +>id : number +>part.subparts[0].id : number +>part.subparts[0] : DeepReadonlyObject +>part.subparts : DeepReadonlyArray +>part : DeepReadonlyObject +>subparts : DeepReadonlyArray +>0 : 0 +>id : number + + part.id = part.id; // Error +>part.id = part.id : number +>part.id : any +>part : DeepReadonlyObject +>id : any +>part.id : number +>part : DeepReadonlyObject +>id : number + + part.subparts[0] = part.subparts[0]; // Error +>part.subparts[0] = part.subparts[0] : DeepReadonlyObject +>part.subparts[0] : DeepReadonlyObject +>part.subparts : DeepReadonlyArray +>part : DeepReadonlyObject +>subparts : DeepReadonlyArray +>0 : 0 +>part.subparts[0] : DeepReadonlyObject +>part.subparts : DeepReadonlyArray +>part : DeepReadonlyObject +>subparts : DeepReadonlyArray +>0 : 0 + + part.subparts[0].id = part.subparts[0].id; // Error +>part.subparts[0].id = part.subparts[0].id : number +>part.subparts[0].id : any +>part.subparts[0] : DeepReadonlyObject +>part.subparts : DeepReadonlyArray +>part : DeepReadonlyObject +>subparts : DeepReadonlyArray +>0 : 0 +>id : any +>part.subparts[0].id : number +>part.subparts[0] : DeepReadonlyObject +>part.subparts : DeepReadonlyArray +>part : DeepReadonlyObject +>subparts : DeepReadonlyArray +>0 : 0 +>id : number + + part.updatePart("hello"); // Error +>part.updatePart("hello") : any +>part.updatePart : any +>part : DeepReadonlyObject +>updatePart : any +>"hello" : "hello" +} + +type ZeroOf = T extends number ? 0 : T extends string ? "" : false; +>ZeroOf : ZeroOf +>T : T +>T : T +>T : T +>false : false + +function zeroOf(value: T) { +>zeroOf : (value: T) => ZeroOf +>T : T +>value : T +>T : T + + return >(typeof value === "number" ? 0 : typeof value === "string" ? "" : false); +>>(typeof value === "number" ? 0 : typeof value === "string" ? "" : false) : ZeroOf +>ZeroOf : ZeroOf +>T : T +>(typeof value === "number" ? 0 : typeof value === "string" ? "" : false) : false | 0 | "" +>typeof value === "number" ? 0 : typeof value === "string" ? "" : false : false | 0 | "" +>typeof value === "number" : boolean +>typeof value : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>value : T +>"number" : "number" +>0 : 0 +>typeof value === "string" ? "" : false : false | "" +>typeof value === "string" : boolean +>typeof value : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>value : T +>"string" : "string" +>"" : "" +>false : false +} + +function f20(n: number, b: boolean, x: number | boolean, y: T) { +>f20 : (n: number, b: boolean, x: number | boolean, y: T) => void +>T : T +>n : number +>b : boolean +>x : number | boolean +>y : T +>T : T + + zeroOf(5); // 0 +>zeroOf(5) : 0 +>zeroOf : (value: T) => ZeroOf +>5 : 5 + + zeroOf("hello"); // "" +>zeroOf("hello") : "" +>zeroOf : (value: T) => ZeroOf +>"hello" : "hello" + + zeroOf(true); // false +>zeroOf(true) : false +>zeroOf : (value: T) => ZeroOf +>true : true + + zeroOf(n); // 0 +>zeroOf(n) : 0 +>zeroOf : (value: T) => ZeroOf +>n : number + + zeroOf(b); // False +>zeroOf(b) : false +>zeroOf : (value: T) => ZeroOf +>b : boolean + + zeroOf(x); // 0 | false +>zeroOf(x) : false | 0 +>zeroOf : (value: T) => ZeroOf +>x : number | boolean + + zeroOf(y); // ZeroOf +>zeroOf(y) : ZeroOf +>zeroOf : (value: T) => ZeroOf +>y : T +} + +function f21(x: T, y: ZeroOf) { +>f21 : (x: T, y: ZeroOf) => void +>T : T +>x : T +>T : T +>y : ZeroOf +>ZeroOf : ZeroOf +>T : T + + let z1: number | string = y; +>z1 : string | number +>y : ZeroOf + + let z2: 0 | "" = y; +>z2 : "" | 0 +>y : ZeroOf + + x = y; // Error +>x = y : ZeroOf +>x : T +>y : ZeroOf + + y = x; // Error +>y = x : T +>y : ZeroOf +>x : T +} + +type Extends = T extends U ? true : false; +>Extends : Extends +>T : T +>U : U +>T : T +>U : U +>true : true +>false : false + +type If = C extends true ? T : F; +>If : If +>C : C +>T : T +>F : F +>C : C +>true : true +>T : T +>F : F + +type Not = If; +>Not : If +>C : C +>If : If +>C : C +>false : false +>true : true + +type And = If; +>And : If +>A : A +>B : B +>If : If +>A : A +>B : B +>false : false + +type Or = If; +>Or : If +>A : A +>B : B +>If : If +>A : A +>true : true +>B : B + +type isString = Extends; +>isString : Extends +>T : T +>Extends : Extends +>T : T + +type Q1 = isString; // false +>Q1 : false +>isString : Extends + +type Q2 = isString<"abc">; // true +>Q2 : true +>isString : Extends + +type Q3 = isString; // boolean +>Q3 : boolean +>isString : Extends + +type Q4 = isString; // boolean +>Q4 : boolean +>isString : Extends + +type N1 = Not; // true +>N1 : true +>Not : If +>false : false + +type N2 = Not; // false +>N2 : false +>Not : If +>true : true + +type N3 = Not; // boolean +>N3 : boolean +>Not : If + +type A1 = And; // false +>A1 : false +>And : If +>false : false +>false : false + +type A2 = And; // false +>A2 : false +>And : If +>false : false +>true : true + +type A3 = And; // false +>A3 : false +>And : If +>true : true +>false : false + +type A4 = And; // true +>A4 : true +>And : If +>true : true +>true : true + +type A5 = And; // false +>A5 : false +>And : If +>false : false + +type A6 = And; // false +>A6 : false +>And : If +>false : false + +type A7 = And; // boolean +>A7 : boolean +>And : If +>true : true + +type A8 = And; // boolean +>A8 : boolean +>And : If +>true : true + +type A9 = And; // boolean +>A9 : boolean +>And : If + +type O1 = Or; // false +>O1 : false +>Or : If +>false : false +>false : false + +type O2 = Or; // true +>O2 : true +>Or : If +>false : false +>true : true + +type O3 = Or; // true +>O3 : true +>Or : If +>true : true +>false : false + +type O4 = Or; // true +>O4 : true +>Or : If +>true : true +>true : true + +type O5 = Or; // boolean +>O5 : boolean +>Or : If +>false : false + +type O6 = Or; // boolean +>O6 : boolean +>Or : If +>false : false + +type O7 = Or; // true +>O7 : true +>Or : If +>true : true + +type O8 = Or; // true +>O8 : true +>Or : If +>true : true + +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 0000000000000..79a0e430cbd67 --- /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 0000000000000..231c39e895242 --- /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 0000000000000..a85f124dede88 --- /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 0000000000000..be974f8661ad9 --- /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/baselines/reference/recursiveTypeRelations.types b/tests/baselines/reference/recursiveTypeRelations.types index 03008690d8dec..ce6d007d06673 100644 --- a/tests/baselines/reference/recursiveTypeRelations.types +++ b/tests/baselines/reference/recursiveTypeRelations.types @@ -97,7 +97,7 @@ export function css(styles: S, ...classNam if (typeof arg == "object") { >typeof arg == "object" : boolean >typeof arg : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" ->arg : keyof S | (object & { [K in keyof S]?: boolean; }) +>arg : object & { [K in keyof S]?: boolean; } >"object" : "object" return Object.keys(arg).reduce((obj: ClassNameObject, key: keyof S) => { @@ -107,7 +107,7 @@ export function css(styles: S, ...classNam >Object.keys : (o: {}) => string[] >Object : ObjectConstructor >keys : (o: {}) => string[] ->arg : keyof S | (object & { [K in keyof S]?: boolean; }) +>arg : object & { [K in keyof S]?: boolean; } >reduce : { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } >ClassNameObject : No type information available! >(obj: ClassNameObject, key: keyof S) => { const exportedClassName = styles[key]; obj[exportedClassName] = (arg as ClassNameMap)[key]; return obj; } : (obj: any, key: keyof S) => any @@ -130,7 +130,7 @@ export function css(styles: S, ...classNam >(arg as ClassNameMap)[key] : { [K in keyof S]?: boolean; }[keyof S] >(arg as ClassNameMap) : { [K in keyof S]?: boolean; } >arg as ClassNameMap : { [K in keyof S]?: boolean; } ->arg : keyof S | (object & { [K in keyof S]?: boolean; }) +>arg : object & { [K in keyof S]?: boolean; } >ClassNameMap : { [K in keyof S]?: boolean; } >S : S >key : keyof S diff --git a/tests/cases/conformance/types/conditional/conditionalTypes1.ts b/tests/cases/conformance/types/conditional/conditionalTypes1.ts new file mode 100644 index 0000000000000..6f4e7dc4188d0 --- /dev/null +++ b/tests/cases/conformance/types/conditional/conditionalTypes1.ts @@ -0,0 +1,202 @@ +// @strict: true +// @declaration: true + +type Diff = T extends U ? never : T; +type Filter = T extends U ? T : never; +type NonNullable = Diff; + +type T00 = Diff<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "b" | "d" +type T01 = Filter<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "a" | "c" + +type T02 = Diff void), Function>; // string | number +type T03 = Filter void), Function>; // () => void + +type T04 = NonNullable; // string | number +type T05 = NonNullable<(() => string) | string[] | null | undefined>; // (() => string) | string[] + +function f1(x: T, y: NonNullable) { + x = y; + y = x; // Error +} + +function f2(x: T, y: NonNullable) { + x = y; + y = x; // Error + let s1: string = x; // Error + let s2: string = y; +} + +function f3(x: Partial[keyof T], y: NonNullable[keyof T]>) { + x = y; + y = x; // Error +} + +type Options = { k: "a", a: number } | { k: "b", b: string } | { k: "c", c: boolean }; + +type T10 = Diff; // { k: "c", c: boolean } +type T11 = Filter; // { k: "a", a: number } | { k: "b", b: string } + +type T12 = Diff; // { k: "c", c: boolean } +type T13 = Filter; // { k: "a", a: number } | { k: "b", b: string } + +type T14 = Diff; // Options +type T15 = Filter; // never + +declare function f4(p: K): Filter; +let x0 = f4("a"); // { k: "a", a: number } + +type OptionsOfKind = Filter; + +type T16 = OptionsOfKind<"a" | "b">; // { k: "a", a: number } | { k: "b", b: string } + +type Select = Filter; + +type T17 = Select; // // { k: "a", a: number } | { k: "b", b: string } + +type TypeName = + T extends string ? "string" : + T extends number ? "number" : + T extends boolean ? "boolean" : + T extends undefined ? "undefined" : + T extends Function ? "function" : + "object"; + +type T20 = TypeName void)>; // "string" | "function" +type T21 = TypeName; // "string" | "number" | "boolean" | "undefined" | "function" | "object" +type T22 = TypeName; // "string" | "number" | "boolean" | "undefined" | "function" | "object" +type T23 = TypeName<{}>; // "object" + +type KnockoutObservable = { object: T }; +type KnockoutObservableArray = { array: T }; + +type KnockedOut = T extends any[] ? KnockoutObservableArray : KnockoutObservable; + +type KnockedOutObj = { + [P in keyof T]: KnockedOut; +} + +interface Item { + id: number; + name: string; + subitems: string[]; +} + +type KOItem = KnockedOutObj; + +interface Part { + id: number; + name: string; + subparts: Part[]; + updatePart(newName: string): void; +} + +type FunctionPropertyNames = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T]; +type FunctionProperties = Pick>; + +type NonFunctionPropertyNames = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]; +type NonFunctionProperties = Pick>; + +type T30 = FunctionProperties; +type T31 = NonFunctionProperties; + +function f7(x: T, y: FunctionProperties, z: NonFunctionProperties) { + x = y; // Error + x = z; // Error + y = x; + y = z; // Error + z = x; + z = y; // Error +} + +function f8(x: keyof T, y: FunctionPropertyNames, z: NonFunctionPropertyNames) { + x = y; + x = z; + y = x; // Error + y = z; // Error + z = x; // Error + z = y; // Error +} + +type DeepReadonly = + T extends any[] ? DeepReadonlyArray : + T extends object ? DeepReadonlyObject : + T; + +interface DeepReadonlyArray extends ReadonlyArray> {} + +type DeepReadonlyObject = { + readonly [P in NonFunctionPropertyNames]: DeepReadonly; +}; + +function f10(part: DeepReadonly) { + let name: string = part.name; + let id: number = part.subparts[0].id; + part.id = part.id; // Error + part.subparts[0] = part.subparts[0]; // Error + part.subparts[0].id = part.subparts[0].id; // Error + part.updatePart("hello"); // Error +} + +type ZeroOf = T extends number ? 0 : T extends string ? "" : false; + +function zeroOf(value: T) { + return >(typeof value === "number" ? 0 : typeof value === "string" ? "" : false); +} + +function f20(n: number, b: boolean, x: number | boolean, y: T) { + zeroOf(5); // 0 + zeroOf("hello"); // "" + zeroOf(true); // false + zeroOf(n); // 0 + zeroOf(b); // False + zeroOf(x); // 0 | false + zeroOf(y); // ZeroOf +} + +function f21(x: T, y: ZeroOf) { + let z1: number | string = y; + let z2: 0 | "" = y; + x = y; // Error + y = x; // Error +} + +type Extends = T extends U ? true : false; +type If = C extends true ? T : F; +type Not = If; +type And = If; +type Or = If; + +type isString = Extends; + +type Q1 = isString; // false +type Q2 = isString<"abc">; // true +type Q3 = isString; // boolean +type Q4 = isString; // boolean + +type N1 = Not; // true +type N2 = Not; // false +type N3 = Not; // boolean + +type A1 = And; // false +type A2 = And; // false +type A3 = And; // false +type A4 = And; // true +type A5 = And; // false +type A6 = And; // false +type A7 = And; // boolean +type A8 = And; // boolean +type A9 = And; // boolean + +type O1 = Or; // false +type O2 = Or; // true +type O3 = Or; // true +type O4 = Or; // true +type O5 = Or; // boolean +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 0000000000000..25552a68acf06 --- /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 1266eb5fad3f5..2d2b47bad3f93 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 57cf08c9ff363..2eedbc8e06286 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')