diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3fbc4cd158b90..9cc867e78534d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -343,6 +343,7 @@ namespace ts { const strictFunctionTypes = getStrictOptionValue(compilerOptions, "strictFunctionTypes"); const strictBindCallApply = getStrictOptionValue(compilerOptions, "strictBindCallApply"); const strictPropertyInitialization = getStrictOptionValue(compilerOptions, "strictPropertyInitialization"); + const strictOptionalProperties = getStrictOptionValue(compilerOptions, "strictOptionalProperties"); const noImplicitAny = getStrictOptionValue(compilerOptions, "noImplicitAny"); const noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis"); const keyofStringsOnly = !!compilerOptions.keyofStringsOnly; @@ -736,6 +737,7 @@ namespace ts { const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined"); const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined, "undefined", ObjectFlags.ContainsWideningType); const optionalType = createIntrinsicType(TypeFlags.Undefined, "undefined"); + const missingType = strictOptionalProperties ? createIntrinsicType(TypeFlags.Undefined, "undefined") : undefinedType; const nullType = createIntrinsicType(TypeFlags.Null, "null"); const nullWideningType = strictNullChecks ? nullType : createIntrinsicType(TypeFlags.Null, "null", ObjectFlags.ContainsWideningType); const stringType = createIntrinsicType(TypeFlags.String, "string"); @@ -4806,7 +4808,7 @@ namespace ts { } const typeParameterNode = typeParameterToDeclarationWithConstraint(getTypeParameterFromMappedType(type), context, appropriateConstraintTypeNode); const nameTypeNode = type.declaration.nameType ? typeToTypeNodeHelper(getNameTypeFromMappedType(type)!, context) : undefined; - const templateTypeNode = typeToTypeNodeHelper(getTemplateTypeFromMappedType(type), context); + const templateTypeNode = typeToTypeNodeHelper(removeMissingType(getTemplateTypeFromMappedType(type), !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), context); const mappedTypeNode = factory.createMappedTypeNode(readonlyToken, typeParameterNode, nameTypeNode, questionToken, templateTypeNode); context.approximateLength += 10; return setEmitFlags(mappedTypeNode, EmitFlags.SingleLine); @@ -4986,7 +4988,7 @@ namespace ts { } function typeReferenceToTypeNode(type: TypeReference) { - const typeArguments: readonly Type[] = getTypeArguments(type); + let typeArguments: readonly Type[] = getTypeArguments(type); if (type.target === globalArrayType || type.target === globalReadonlyArrayType) { if (context.flags & NodeBuilderFlags.WriteArrayAsGenericType) { const typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context); @@ -4997,6 +4999,7 @@ namespace ts { return type.target === globalArrayType ? arrayType : factory.createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, arrayType); } else if (type.target.objectFlags & ObjectFlags.Tuple) { + typeArguments = sameMap(typeArguments, (t, i) => removeMissingType(t, !!((type.target as TupleType).elementFlags[i] & ElementFlags.Optional))); if (typeArguments.length > 0) { const arity = getTypeReferenceArity(type); const tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, arity), context); @@ -5229,7 +5232,7 @@ namespace ts { function addPropertyToElementList(propertySymbol: Symbol, context: NodeBuilderContext, typeElements: TypeElement[]) { const propertyIsReverseMapped = !!(getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped); const propertyType = shouldUsePlaceholderForProperty(propertySymbol, context) ? - anyType : getTypeOfSymbol(propertySymbol); + anyType : getNonMissingTypeOfSymbol(propertySymbol); const saveEnclosingDeclaration = context.enclosingDeclaration; context.enclosingDeclaration = undefined; if (context.tracker.trackSymbol && getCheckFlags(propertySymbol) & CheckFlags.Late && isLateBoundName(propertySymbol.escapedName)) { @@ -8365,8 +8368,8 @@ namespace ts { return expr.kind === SyntaxKind.ArrayLiteralExpression && (expr as ArrayLiteralExpression).elements.length === 0; } - function addOptionality(type: Type, optional = true): Type { - return strictNullChecks && optional ? getOptionalType(type) : type; + function addOptionality(type: Type, isProperty = false, isOptional = true): Type { + return strictNullChecks && isOptional ? getOptionalType(type, isProperty) : type; } // Return the inferred type for a variable, parameter, or property declaration @@ -8391,15 +8394,16 @@ namespace ts { return getTypeForBindingElement(declaration as BindingElement); } + const isProperty = isPropertyDeclaration(declaration) || isPropertySignature(declaration); const isOptional = includeOptionality && ( - isParameter(declaration) && isJSDocOptionalParameter(declaration) - || isOptionalJSDocPropertyLikeTag(declaration) - || !isBindingElement(declaration) && !isVariableDeclaration(declaration) && !!declaration.questionToken); + isProperty && !!(declaration as PropertyDeclaration | PropertySignature).questionToken || + isParameter(declaration) && (!!declaration.questionToken || isJSDocOptionalParameter(declaration)) || + isOptionalJSDocPropertyLikeTag(declaration)); // Use type from type annotation if one is present const declaredType = tryGetTypeFromEffectiveTypeNode(declaration); if (declaredType) { - return addOptionality(declaredType, isOptional); + return addOptionality(declaredType, isProperty, isOptional); } if ((noImplicitAny || isInJSFile(declaration)) && @@ -8445,7 +8449,7 @@ namespace ts { // Use contextual parameter type if one is available const type = declaration.symbol.escapedName === InternalSymbolName.This ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration); if (type) { - return addOptionality(type, isOptional); + return addOptionality(type, /*isProperty*/ false, isOptional); } } @@ -8459,7 +8463,7 @@ namespace ts { } } const type = widenTypeInferredFromInitializer(declaration, checkDeclarationInitializer(declaration)); - return addOptionality(type, isOptional); + return addOptionality(type, isProperty, isOptional); } if (isPropertyDeclaration(declaration) && !hasStaticModifier(declaration) && (noImplicitAny || isInJSFile(declaration))) { @@ -8469,7 +8473,7 @@ namespace ts { const type = constructor ? getFlowTypeInConstructor(declaration.symbol, constructor) : getEffectiveModifierFlags(declaration) & ModifierFlags.Ambient ? getTypeOfPropertyInBaseClass(declaration.symbol) : undefined; - return type && addOptionality(type, isOptional); + return type && addOptionality(type, /*isProperty*/ true, isOptional); } if (isJsxAttribute(declaration)) { @@ -8636,7 +8640,7 @@ namespace ts { type = getUnionType(sourceTypes!, UnionReduction.Subtype); } } - const widened = getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor)); + const widened = getWidenedType(addOptionality(type, /*isProperty*/ false, definedInMethod && !definedInConstructor)); if (symbol.valueDeclaration && filterType(widened, t => !!(t.flags & ~TypeFlags.Nullable)) === neverType) { reportImplicitAny(symbol.valueDeclaration, anyType); return anyType; @@ -8679,7 +8683,10 @@ namespace ts { if (symbol.parent?.valueDeclaration) { const typeNode = getEffectiveTypeAnnotationNode(symbol.parent.valueDeclaration); if (typeNode) { - return getTypeOfPropertyOfType(getTypeFromTypeNode(typeNode), symbol.escapedName); + const annotationSymbol = getPropertyOfType(getTypeFromTypeNode(typeNode), symbol.escapedName); + if (annotationSymbol) { + return getNonMissingTypeOfSymbol(annotationSymbol); + } } } @@ -9384,6 +9391,10 @@ namespace ts { return errorType; } + function getNonMissingTypeOfSymbol(symbol: Symbol) { + return removeMissingType(getTypeOfSymbol(symbol), !!(symbol.flags & SymbolFlags.Optional)); + } + function isReferenceToType(type: Type, target: Type) { return type !== undefined && target !== undefined @@ -11168,7 +11179,7 @@ namespace ts { // When creating an optional property in strictNullChecks mode, if 'undefined' isn't assignable to the // type, we include 'undefined' in the type. Similarly, when creating a non-optional property in strictNullChecks // mode, if the underlying property is optional we remove 'undefined' from the type. - let type = strictNullChecks && symbol.flags & SymbolFlags.Optional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType) : + let type = strictNullChecks && symbol.flags & SymbolFlags.Optional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType, /*isProperty*/ true) : symbol.checkFlags & CheckFlags.StripOptional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : propType; if (!popTypeResolution()) { @@ -11199,7 +11210,7 @@ namespace ts { function getTemplateTypeFromMappedType(type: MappedType) { return type.templateType || (type.templateType = type.declaration.type ? - instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), type.mapper) : + instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), /*isProperty*/ true, !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), type.mapper) : errorType); } @@ -13680,8 +13691,7 @@ namespace ts { } function getTypeFromOptionalTypeNode(node: OptionalTypeNode): Type { - const type = getTypeFromTypeNode(node.type); - return strictNullChecks ? getOptionalType(type) : type; + return addOptionality(getTypeFromTypeNode(node.type), /*isProperty*/ true); } function getTypeId(type: Type): TypeId { @@ -13871,6 +13881,12 @@ namespace ts { if (includes & TypeFlags.AnyOrUnknown) { return includes & TypeFlags.Any ? includes & TypeFlags.IncludesWildcard ? wildcardType : anyType : unknownType; } + if (strictOptionalProperties && includes & TypeFlags.Undefined) { + const missingIndex = binarySearch(typeSet, missingType, getTypeId, compareValues); + if (missingIndex >= 0 && containsType(typeSet, undefinedType)) { + orderedRemoveItemAt(typeSet, missingIndex); + } + } if (includes & (TypeFlags.Literal | TypeFlags.UniqueESSymbol) || includes & TypeFlags.Void && includes & TypeFlags.Undefined) { removeRedundantLiteralTypes(typeSet, includes, !!(unionReduction & UnionReduction.Subtype)); } @@ -15390,7 +15406,7 @@ namespace ts { const isSetonlyAccessor = prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor); const flags = SymbolFlags.Property | SymbolFlags.Optional; const result = createSymbol(flags, prop.escapedName, getIsLateCheckFlag(prop) | (readonly ? CheckFlags.Readonly : 0)); - result.type = isSetonlyAccessor ? undefinedType : getUnionType([getTypeOfSymbol(prop), undefinedType]); + result.type = isSetonlyAccessor ? undefinedType : addOptionality(getTypeOfSymbol(prop), /*isProperty*/ true); result.declarations = prop.declarations; result.nameType = getSymbolLinks(prop).nameType; result.syntheticOrigin = prop; @@ -15688,8 +15704,7 @@ namespace ts { const links = getNodeLinks(node); return links.resolvedType || (links.resolvedType = node.dotDotDotToken ? getTypeFromRestTypeNode(node) : - node.questionToken && strictNullChecks ? getOptionalType(getTypeFromTypeNode(node.type)) : - getTypeFromTypeNode(node.type)); + addOptionality(getTypeFromTypeNode(node.type), /*isProperty*/ true, !!node.questionToken)); } function getTypeFromTypeNode(node: TypeNode): Type { @@ -16152,7 +16167,7 @@ namespace ts { const templateMapper = appendTypeMapping(mapper, getTypeParameterFromMappedType(type), key); const propType = instantiateType(getTemplateTypeFromMappedType(type.target as MappedType || type), templateMapper); const modifiers = getMappedTypeModifiers(type); - return strictNullChecks && modifiers & MappedTypeModifiers.IncludeOptional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType) : + return strictNullChecks && modifiers & MappedTypeModifiers.IncludeOptional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType, /*isProperty*/ true) : strictNullChecks && modifiers & MappedTypeModifiers.ExcludeOptional && isOptional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : propType; } @@ -16698,10 +16713,16 @@ namespace ts { let reportedError = false; for (let status = iterator.next(); !status.done; status = iterator.next()) { const { errorNode: prop, innerExpression: next, nameType, errorMessage } = status.value; - const targetPropType = getBestMatchIndexedAccessTypeOrUndefined(source, target, nameType); + let targetPropType = getBestMatchIndexedAccessTypeOrUndefined(source, target, nameType); if (!targetPropType || targetPropType.flags & TypeFlags.IndexedAccess) continue; // Don't elaborate on indexes on generic variables - const sourcePropType = getIndexedAccessTypeOrUndefined(source, nameType); - if (sourcePropType && !checkTypeRelatedTo(sourcePropType, targetPropType, relation, /*errorNode*/ undefined)) { + let sourcePropType = getIndexedAccessTypeOrUndefined(source, nameType); + if (!sourcePropType) continue; + const propName = getPropertyNameFromIndex(nameType, /*accessNode*/ undefined); + const targetIsOptional = !!(propName && (getPropertyOfType(target, propName) || unknownSymbol).flags & SymbolFlags.Optional); + const sourceIsOptional = !!(propName && (getPropertyOfType(source, propName) || unknownSymbol).flags & SymbolFlags.Optional); + targetPropType = removeMissingType(targetPropType, targetIsOptional); + sourcePropType = removeMissingType(sourcePropType, targetIsOptional && sourceIsOptional); + if (!checkTypeRelatedTo(sourcePropType, targetPropType, relation, /*errorNode*/ undefined)) { const elaborated = next && elaborateError(next, sourcePropType, targetPropType, relation, /*headMessage*/ undefined, containingMessageChain, errorOutputContainer); if (elaborated) { reportedError = true; @@ -18877,7 +18898,7 @@ namespace ts { // fixed limit before incurring the cost of any allocations: let numCombinations = 1; for (const sourceProperty of sourcePropertiesFiltered) { - numCombinations *= countTypes(getTypeOfSymbol(sourceProperty)); + numCombinations *= countTypes(getNonMissingTypeOfSymbol(sourceProperty)); if (numCombinations > 25) { // We've reached the complexity limit. tracing?.instant(tracing.Phase.CheckTypes, "typeRelatedToDiscriminatedType_DepthLimit", { sourceId: source.id, targetId: target.id, numCombinations }); @@ -18890,7 +18911,7 @@ namespace ts { const excludedProperties = new Set<__String>(); for (let i = 0; i < sourcePropertiesFiltered.length; i++) { const sourceProperty = sourcePropertiesFiltered[i]; - const sourcePropertyType = getTypeOfSymbol(sourceProperty); + const sourcePropertyType = getNonMissingTypeOfSymbol(sourceProperty); sourceDiscriminantTypes[i] = sourcePropertyType.flags & TypeFlags.Union ? (sourcePropertyType as UnionType).types : [sourcePropertyType]; @@ -18971,45 +18992,9 @@ namespace ts { function isPropertySymbolTypeRelated(sourceProp: Symbol, targetProp: Symbol, getTypeOfSourceProperty: (sym: Symbol) => Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary { const targetIsOptional = strictNullChecks && !!(getCheckFlags(targetProp) & CheckFlags.Partial); - const source = getTypeOfSourceProperty(sourceProp); - if (getCheckFlags(targetProp) & CheckFlags.DeferredType && !getSymbolLinks(targetProp).type) { - // Rather than resolving (and normalizing) the type, relate constituent-by-constituent without performing normalization or seconadary passes - const links = getSymbolLinks(targetProp); - Debug.assertIsDefined(links.deferralParent); - Debug.assertIsDefined(links.deferralConstituents); - const unionParent = !!(links.deferralParent.flags & TypeFlags.Union); - let result = unionParent ? Ternary.False : Ternary.True; - const targetTypes = links.deferralConstituents; - for (const targetType of targetTypes) { - const related = isRelatedTo(source, targetType, /*reportErrors*/ false, /*headMessage*/ undefined, unionParent ? 0 : IntersectionState.Target); - if (!unionParent) { - if (!related) { - // Can't assign to a target individually - have to fallback to assigning to the _whole_ intersection (which forces normalization) - return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors); - } - result &= related; - } - else { - if (related) { - return related; - } - } - } - if (unionParent && !result && targetIsOptional) { - result = isRelatedTo(source, undefinedType); - } - if (unionParent && !result && reportErrors) { - // The easiest way to get the right errors here is to un-defer (which may be costly) - // If it turns out this is too costly too often, we can replicate the error handling logic within - // typeRelatedToSomeType without the discriminatable type branch (as that requires a manifest union - // type on which to hand discriminable properties, which we are expressly trying to avoid here) - return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors); - } - return result; - } - else { - return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors, /*headMessage*/ undefined, intersectionState); - } + const effectiveTarget = addOptionality(getNonMissingTypeOfSymbol(targetProp), /*isProperty*/ false, targetIsOptional); + const effectiveSource = getTypeOfSourceProperty(sourceProp); + return isRelatedTo(effectiveSource, effectiveTarget, reportErrors, /*headMessage*/ undefined, intersectionState); } function propertyRelatedTo(source: Type, target: Type, sourceProp: Symbol, targetProp: Symbol, getTypeOfSourceProperty: (sym: Symbol) => Type, reportErrors: boolean, intersectionState: IntersectionState, skipOptional: boolean): Ternary { @@ -19150,7 +19135,7 @@ namespace ts { } return Ternary.False; } - if (!targetRestFlag && sourceRestFlag) { + if (!targetRestFlag && (sourceRestFlag || targetArity < sourceArity)) { if (reportErrors) { if (sourceMinLength < targetMinLength) { reportError(Diagnostics.Target_requires_0_element_s_but_source_may_have_fewer, targetMinLength); @@ -19198,10 +19183,11 @@ namespace ts { } } const sourceType = !isTupleType(source) ? sourceTypeArguments[0] : - i < startCount || i >= targetArity - endCount ? sourceTypeArguments[sourceIndex] : + i < startCount || i >= targetArity - endCount ? removeMissingType(sourceTypeArguments[sourceIndex], !!(sourceFlags & targetFlags & ElementFlags.Optional)) : getElementTypeOfSliceOfTupleType(source, startCount, endCount) || neverType; const targetType = targetTypeArguments[i]; - const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : targetType; + const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : + removeMissingType(targetType, !!(targetFlags & ElementFlags.Optional)); const related = isRelatedTo(sourceType, targetCheckType, reportErrors, /*headMessage*/ undefined, intersectionState); if (!related) { if (reportErrors) { @@ -19234,7 +19220,7 @@ namespace ts { for (const sourceProp of excludeProperties(getPropertiesOfType(source), excludedProperties)) { if (!getPropertyOfObjectType(target, sourceProp.escapedName)) { const sourceType = getTypeOfSymbol(sourceProp); - if (!(sourceType === undefinedType || sourceType === undefinedWideningType || sourceType === optionalType)) { + if (!(sourceType.flags & TypeFlags.Undefined)) { if (reportErrors) { reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(sourceProp), typeToString(target)); } @@ -19252,7 +19238,7 @@ namespace ts { if (!(targetProp.flags & SymbolFlags.Prototype) && (!numericNamesOnly || isNumericLiteralName(name) || name === "length")) { const sourceProp = getPropertyOfType(source, name); if (sourceProp && sourceProp !== targetProp) { - const related = propertyRelatedTo(source, target, sourceProp, targetProp, getTypeOfSymbol, reportErrors, intersectionState, relation === comparableRelation); + const related = propertyRelatedTo(source, target, sourceProp, targetProp, getNonMissingTypeOfSymbol, reportErrors, intersectionState, relation === comparableRelation); if (!related) { return Ternary.False; } @@ -20319,9 +20305,9 @@ namespace ts { getUnionType([type, undefinedType, nullType]); } - function getOptionalType(type: Type): Type { + function getOptionalType(type: Type, isProperty = false): Type { Debug.assert(strictNullChecks); - return type.flags & TypeFlags.Undefined ? type : getUnionType([type, undefinedType]); + return type.flags & TypeFlags.Undefined ? type : getUnionType([type, isProperty ? missingType : undefinedType]); } function getGlobalNonNullableTypeInstantiation(type: Type) { @@ -20364,6 +20350,14 @@ namespace ts { exprType; } + function removeMissingType(type: Type, isOptional: boolean) { + return strictOptionalProperties && isOptional ? filterType(type, t => t !== missingType) : type; + } + + function containsMissingType(type: Type) { + return strictOptionalProperties && (type === missingType || type.flags & TypeFlags.Union && containsType((type as UnionType).types, missingType)); + } + /** * Is source potentially coercible to target type under `==`. * Assumes that `source` is a constituent of a union, hence @@ -20507,7 +20501,7 @@ namespace ts { if (cached) { return cached; } - const result = createSymbolWithType(prop, undefinedType); + const result = createSymbolWithType(prop, missingType); result.flags |= SymbolFlags.Optional; undefinedProperties.set(prop.escapedName, result); return result; @@ -23570,8 +23564,14 @@ namespace ts { return narrowTypeByInstanceof(type, expr, assumeTrue); case SyntaxKind.InKeyword: const target = getReferenceCandidate(expr.right); - if (isStringLiteralLike(expr.left) && isMatchingReference(reference, target)) { - return narrowByInKeyword(type, expr.left, assumeTrue); + if (isStringLiteralLike(expr.left)) { + if (containsMissingType(type) && isAccessExpression(reference) && isMatchingReference(reference.expression, target) && + getAccessedPropertyName(reference) === escapeLeadingUnderscores(expr.left.text)) { + return getTypeWithFacts(type, assumeTrue ? TypeFacts.NEUndefined : TypeFacts.EQUndefined); + } + if (isMatchingReference(reference, target)) { + return narrowByInKeyword(type, expr.left, assumeTrue); + } } break; case SyntaxKind.CommaToken: @@ -23957,6 +23957,16 @@ namespace ts { return narrowTypeByTypePredicate(type, predicate, callExpression, assumeTrue); } } + if (containsMissingType(type) && isAccessExpression(reference) && isPropertyAccessExpression(callExpression.expression)) { + const callAccess = callExpression.expression; + if (isMatchingReference(reference.expression, getReferenceCandidate(callAccess.expression)) && + isIdentifier(callAccess.name) && callAccess.name.escapedText === "hasOwnProperty" && callExpression.arguments.length === 1) { + const argument = callExpression.arguments[0]; + if (isStringLiteralLike(argument) && getAccessedPropertyName(reference) === escapeLeadingUnderscores(argument.text)) { + return getTypeWithFacts(type, assumeTrue ? TypeFacts.NEUndefined : TypeFacts.EQUndefined); + } + } + } return type; } @@ -24048,7 +24058,7 @@ namespace ts { // to it at the given location. Since we have no control flow information for the // hypothetical reference (control flow information is created and attached by the // binder), we simply return the declared type of the symbol. - return getTypeOfSymbol(symbol); + return getNonMissingTypeOfSymbol(symbol); } function getControlFlowContainer(node: Node): Node { @@ -26014,6 +26024,7 @@ namespace ts { const contextualType = getApparentTypeOfContextualType(node); const inDestructuringPattern = isAssignmentTarget(node); const inConstContext = isConstContext(node); + let hasOmittedExpression = false; for (let i = 0; i < elementCount; i++) { const e = elements[i]; if (e.kind === SyntaxKind.SpreadElement) { @@ -26049,11 +26060,16 @@ namespace ts { elementFlags.push(ElementFlags.Rest); } } + else if (strictOptionalProperties && e.kind === SyntaxKind.OmittedExpression) { + hasOmittedExpression = true; + elementTypes.push(missingType); + elementFlags.push(ElementFlags.Optional); + } else { const elementContextualType = getContextualTypeForElementExpression(contextualType, elementTypes.length); const type = checkExpressionForMutableLocation(e, checkMode, elementContextualType, forceTuple); - elementTypes.push(type); - elementFlags.push(ElementFlags.Required); + elementTypes.push(addOptionality(type, /*isProperty*/ true, hasOmittedExpression)); + elementFlags.push(hasOmittedExpression ? ElementFlags.Optional : ElementFlags.Required); } } if (inDestructuringPattern) { @@ -27478,8 +27494,10 @@ namespace ts { // assignment target, and the referenced property was declared as a variable, property, // accessor, or optional method. const assignmentKind = getAssignmentTargetKind(node); - if (assignmentKind === AssignmentKind.Definite || - prop && + if (assignmentKind === AssignmentKind.Definite) { + return removeMissingType(propType, !!(prop && prop.flags & SymbolFlags.Optional)); + } + if (prop && !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) && !(prop.flags & SymbolFlags.Method && propType.flags & TypeFlags.Union) && !isDuplicatedCommonJSExport(prop.declarations)) { @@ -36886,7 +36904,7 @@ namespace ts { if (stringIndexType || numberIndexType) { forEach(getPropertiesOfObjectType(type), prop => { if (isStatic && prop.flags & SymbolFlags.Prototype) return; - const propType = getTypeOfSymbol(prop); + const propType = getNonMissingTypeOfSymbol(prop); checkIndexConstraintForProperty(prop, propType, type, declaredStringIndexer, stringIndexType, IndexKind.String); checkIndexConstraintForProperty(prop, propType, type, declaredNumberIndexer, numberIndexType, IndexKind.Number); }); @@ -36899,7 +36917,7 @@ namespace ts { // and properties with literal names were already checked. if (!hasSyntacticModifier(member, ModifierFlags.Static) && !hasBindableName(member)) { const symbol = getSymbolOfNode(member); - const propType = getTypeOfSymbol(symbol); + const propType = getNonMissingTypeOfSymbol(symbol); checkIndexConstraintForProperty(symbol, propType, type, declaredStringIndexer, stringIndexType, IndexKind.String); checkIndexConstraintForProperty(symbol, propType, type, declaredNumberIndexer, numberIndexType, IndexKind.Number); } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 4fec5cd18caf4..3cc666af682bd 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -612,6 +612,15 @@ namespace ts { category: Diagnostics.Strict_Type_Checking_Options, description: Diagnostics.Enable_strict_checking_of_property_initialization_in_classes }, + { + name: "strictOptionalProperties", + type: "boolean", + affectsSemanticDiagnostics: true, + strictFlag: true, + showInSimplifiedHelpView: true, + category: Diagnostics.Strict_Type_Checking_Options, + description: Diagnostics.Enable_strict_checking_of_optional_properties + }, { name: "noImplicitThis", type: "boolean", diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0c766fbde12c9..0998b3a18314e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4873,6 +4873,10 @@ "category": "Message", "code": 6242 }, + "Enable strict checking of optional properties.": { + "category": "Message", + "code": 6243 + }, "Projects to reference": { "category": "Message", diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 102517c4ce6fd..e3eb5538d4be6 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -3041,6 +3041,9 @@ namespace ts { if (options.strictPropertyInitialization && !getStrictOptionValue(options, "strictNullChecks")) { createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks"); } + if (options.strictOptionalProperties && !getStrictOptionValue(options, "strictNullChecks")) { + createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictOptionalProperties", "strictNullChecks"); + } if (options.isolatedModules) { if (options.out) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f395014baad1d..5c8992a69a60d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6041,6 +6041,7 @@ namespace ts { strictBindCallApply?: boolean; // Always combine with strict property strictNullChecks?: boolean; // Always combine with strict property strictPropertyInitialization?: boolean; // Always combine with strict property + strictOptionalProperties?: boolean; // Always combine with strict property stripInternal?: boolean; suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 8271e6adfc22f..683d505a97f58 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -6109,6 +6109,7 @@ namespace ts { | "strictFunctionTypes" | "strictBindCallApply" | "strictPropertyInitialization" + | "strictOptionalProperties" | "alwaysStrict" ; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index dcbd016c31e3b..6f94fa1b356ed 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2913,6 +2913,7 @@ declare namespace ts { strictBindCallApply?: boolean; strictNullChecks?: boolean; strictPropertyInitialization?: boolean; + strictOptionalProperties?: boolean; stripInternal?: boolean; suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index a3d17250a215c..9f58cc3bbab09 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2913,6 +2913,7 @@ declare namespace ts { strictBindCallApply?: boolean; strictNullChecks?: boolean; strictPropertyInitialization?: boolean; + strictOptionalProperties?: boolean; stripInternal?: boolean; suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; diff --git a/tests/baselines/reference/checkJsxIntersectionElementPropsType.types b/tests/baselines/reference/checkJsxIntersectionElementPropsType.types index 187d0f274a409..efaa22d38c6e4 100644 --- a/tests/baselines/reference/checkJsxIntersectionElementPropsType.types +++ b/tests/baselines/reference/checkJsxIntersectionElementPropsType.types @@ -16,7 +16,7 @@ declare class Component

{ class C extends Component<{ x?: boolean; } & T> {} >C : C ->Component : Component<{ x?: boolean | undefined; } & T> +>Component : Component<{ x?: boolean; } & T> >x : boolean | undefined const y = new C({foobar: "example"}); diff --git a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.types b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.types index babef6106a169..8f5250d3e4789 100644 --- a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.types +++ b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.types @@ -10,7 +10,7 @@ declare class Component

{ >context : any readonly props: Readonly

& Readonly<{ children?: {} }>; ->props : Readonly

& Readonly<{ children?: {} | undefined; }> +>props : Readonly

& Readonly<{ children?: {}; }> >children : {} | undefined } interface ComponentClass

{ @@ -29,7 +29,7 @@ interface ComponentClass

{ } interface FunctionComponent

{ (props: P & { children?: {} }, context?: any): {} | null; ->props : P & { children?: {} | undefined; } +>props : P & { children?: {}; } >children : {} | undefined >context : any >null : null diff --git a/tests/baselines/reference/contextuallyTypedParametersWithInitializers.types b/tests/baselines/reference/contextuallyTypedParametersWithInitializers.types index db65878b320d3..b49c5d763304c 100644 --- a/tests/baselines/reference/contextuallyTypedParametersWithInitializers.types +++ b/tests/baselines/reference/contextuallyTypedParametersWithInitializers.types @@ -16,7 +16,7 @@ declare function id3 any>(input: T): T; declare function id4 any>(input: T): T; >id4 : any>(input: T) => T ->x : { foo?: number | undefined; } +>x : { foo?: number; } >foo : number | undefined >input : T @@ -60,10 +60,10 @@ const f13 = id3(function ({ foo = 42 }) { return foo }); >foo : any const f14 = id4(function ({ foo = 42 }) { return foo }); ->f14 : ({ foo }: { foo?: number | undefined; }) => number ->id4(function ({ foo = 42 }) { return foo }) : ({ foo }: { foo?: number | undefined; }) => number ->id4 : any>(input: T) => T ->function ({ foo = 42 }) { return foo } : ({ foo }: { foo?: number | undefined; }) => number +>f14 : ({ foo }: { foo?: number; }) => number +>id4(function ({ foo = 42 }) { return foo }) : ({ foo }: { foo?: number; }) => number +>id4 : any>(input: T) => T +>function ({ foo = 42 }) { return foo } : ({ foo }: { foo?: number; }) => number >foo : number >42 : 42 >foo : number diff --git a/tests/baselines/reference/controlFlowOptionalChain.types b/tests/baselines/reference/controlFlowOptionalChain.types index 4e335fca6d287..4fc4faf8fce59 100644 --- a/tests/baselines/reference/controlFlowOptionalChain.types +++ b/tests/baselines/reference/controlFlowOptionalChain.types @@ -249,256 +249,256 @@ o3.x; >x : 1 | 2 declare const o4: { x?: { y: boolean } }; ->o4 : { x?: { y: boolean; } | undefined; } +>o4 : { x?: { y: boolean;}; } >x : { y: boolean; } | undefined >y : boolean if (o4.x?.y) { >o4.x?.y : boolean | undefined >o4.x : { y: boolean; } | undefined ->o4 : { x?: { y: boolean; } | undefined; } +>o4 : { x?: { y: boolean; }; } >x : { y: boolean; } | undefined >y : boolean | undefined o4.x; // { y: boolean } >o4.x : { y: boolean; } ->o4 : { x?: { y: boolean; } | undefined; } +>o4 : { x?: { y: boolean; }; } >x : { y: boolean; } o4.x.y; // true >o4.x.y : true >o4.x : { y: boolean; } ->o4 : { x?: { y: boolean; } | undefined; } +>o4 : { x?: { y: boolean; }; } >x : { y: boolean; } >y : true o4.x?.y; // true >o4.x?.y : true >o4.x : { y: boolean; } ->o4 : { x?: { y: boolean; } | undefined; } +>o4 : { x?: { y: boolean; }; } >x : { y: boolean; } >y : true } else { o4.x; >o4.x : { y: boolean; } | undefined ->o4 : { x?: { y: boolean; } | undefined; } +>o4 : { x?: { y: boolean; }; } >x : { y: boolean; } | undefined o4.x?.y; >o4.x?.y : boolean | undefined >o4.x : { y: boolean; } | undefined ->o4 : { x?: { y: boolean; } | undefined; } +>o4 : { x?: { y: boolean; }; } >x : { y: boolean; } | undefined >y : boolean | undefined o4.x.y; >o4.x.y : boolean >o4.x : { y: boolean; } | undefined ->o4 : { x?: { y: boolean; } | undefined; } +>o4 : { x?: { y: boolean; }; } >x : { y: boolean; } | undefined >y : boolean } o4.x; >o4.x : { y: boolean; } | undefined ->o4 : { x?: { y: boolean; } | undefined; } +>o4 : { x?: { y: boolean; }; } >x : { y: boolean; } | undefined o4.x?.y; >o4.x?.y : boolean | undefined >o4.x : { y: boolean; } | undefined ->o4 : { x?: { y: boolean; } | undefined; } +>o4 : { x?: { y: boolean; }; } >x : { y: boolean; } | undefined >y : boolean | undefined o4.x.y; >o4.x.y : boolean >o4.x : { y: boolean; } | undefined ->o4 : { x?: { y: boolean; } | undefined; } +>o4 : { x?: { y: boolean; }; } >x : { y: boolean; } | undefined >y : boolean declare const o5: { x?: { y: { z?: { w: boolean } } } }; ->o5 : { x?: { y: { z?: { w: boolean; };}; } | undefined; } +>o5 : { x?: { y: { z?: { w: boolean; }; };}; } >x : { y: { z?: { w: boolean; };}; } | undefined ->y : { z?: { w: boolean; } | undefined; } +>y : { z?: { w: boolean;}; } >z : { w: boolean; } | undefined >w : boolean if (o5.x?.y.z?.w) { >o5.x?.y.z?.w : boolean | undefined >o5.x?.y.z : { w: boolean; } | undefined ->o5.x?.y : { z?: { w: boolean; } | undefined; } | undefined ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->y : { z?: { w: boolean; } | undefined; } | undefined +>o5.x?.y : { z?: { w: boolean; }; } | undefined +>o5.x : { y: { z?: { w: boolean; }; }; } | undefined +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } | undefined +>y : { z?: { w: boolean; }; } | undefined >z : { w: boolean; } | undefined >w : boolean | undefined o5.x; ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } +>o5.x : { y: { z?: { w: boolean; }; }; } +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } o5.x.y; ->o5.x.y : { z?: { w: boolean; } | undefined; } ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } ->y : { z?: { w: boolean; } | undefined; } +>o5.x.y : { z?: { w: boolean; }; } +>o5.x : { y: { z?: { w: boolean; }; }; } +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } +>y : { z?: { w: boolean; }; } o5.x.y.z; >o5.x.y.z : { w: boolean; } ->o5.x.y : { z?: { w: boolean; } | undefined; } ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } ->y : { z?: { w: boolean; } | undefined; } +>o5.x.y : { z?: { w: boolean; }; } +>o5.x : { y: { z?: { w: boolean; }; }; } +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } +>y : { z?: { w: boolean; }; } >z : { w: boolean; } o5.x.y.z.w; // true >o5.x.y.z.w : true >o5.x.y.z : { w: boolean; } ->o5.x.y : { z?: { w: boolean; } | undefined; } ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } ->y : { z?: { w: boolean; } | undefined; } +>o5.x.y : { z?: { w: boolean; }; } +>o5.x : { y: { z?: { w: boolean; }; }; } +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } +>y : { z?: { w: boolean; }; } >z : { w: boolean; } >w : true o5.x.y.z?.w; // true >o5.x.y.z?.w : true >o5.x.y.z : { w: boolean; } ->o5.x.y : { z?: { w: boolean; } | undefined; } ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } ->y : { z?: { w: boolean; } | undefined; } +>o5.x.y : { z?: { w: boolean; }; } +>o5.x : { y: { z?: { w: boolean; }; }; } +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } +>y : { z?: { w: boolean; }; } >z : { w: boolean; } >w : true o5.x?.y.z.w; // true >o5.x?.y.z.w : true >o5.x?.y.z : { w: boolean; } ->o5.x?.y : { z?: { w: boolean; } | undefined; } ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } ->y : { z?: { w: boolean; } | undefined; } +>o5.x?.y : { z?: { w: boolean; }; } +>o5.x : { y: { z?: { w: boolean; }; }; } +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } +>y : { z?: { w: boolean; }; } >z : { w: boolean; } >w : true o5.x?.y.z?.w; // true >o5.x?.y.z?.w : true >o5.x?.y.z : { w: boolean; } ->o5.x?.y : { z?: { w: boolean; } | undefined; } ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } ->y : { z?: { w: boolean; } | undefined; } +>o5.x?.y : { z?: { w: boolean; }; } +>o5.x : { y: { z?: { w: boolean; }; }; } +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } +>y : { z?: { w: boolean; }; } >z : { w: boolean; } >w : true } else { o5.x; ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } | undefined +>o5.x : { y: { z?: { w: boolean; }; }; } | undefined +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } | undefined o5.x?.y; ->o5.x?.y : { z?: { w: boolean; } | undefined; } | undefined ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->y : { z?: { w: boolean; } | undefined; } | undefined +>o5.x?.y : { z?: { w: boolean; }; } | undefined +>o5.x : { y: { z?: { w: boolean; }; }; } | undefined +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } | undefined +>y : { z?: { w: boolean; }; } | undefined o5.x?.y.z; >o5.x?.y.z : { w: boolean; } | undefined ->o5.x?.y : { z?: { w: boolean; } | undefined; } | undefined ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->y : { z?: { w: boolean; } | undefined; } | undefined +>o5.x?.y : { z?: { w: boolean; }; } | undefined +>o5.x : { y: { z?: { w: boolean; }; }; } | undefined +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } | undefined +>y : { z?: { w: boolean; }; } | undefined >z : { w: boolean; } | undefined o5.x?.y.z?.w; >o5.x?.y.z?.w : boolean | undefined >o5.x?.y.z : { w: boolean; } | undefined ->o5.x?.y : { z?: { w: boolean; } | undefined; } | undefined ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->y : { z?: { w: boolean; } | undefined; } | undefined +>o5.x?.y : { z?: { w: boolean; }; } | undefined +>o5.x : { y: { z?: { w: boolean; }; }; } | undefined +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } | undefined +>y : { z?: { w: boolean; }; } | undefined >z : { w: boolean; } | undefined >w : boolean | undefined o5.x.y; ->o5.x.y : { z?: { w: boolean; } | undefined; } ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->y : { z?: { w: boolean; } | undefined; } +>o5.x.y : { z?: { w: boolean; }; } +>o5.x : { y: { z?: { w: boolean; }; }; } | undefined +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } | undefined +>y : { z?: { w: boolean; }; } o5.x.y.z.w; >o5.x.y.z.w : boolean >o5.x.y.z : { w: boolean; } | undefined ->o5.x.y : { z?: { w: boolean; } | undefined; } ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->y : { z?: { w: boolean; } | undefined; } +>o5.x.y : { z?: { w: boolean; }; } +>o5.x : { y: { z?: { w: boolean; }; }; } | undefined +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } | undefined +>y : { z?: { w: boolean; }; } >z : { w: boolean; } | undefined >w : boolean } o5.x; ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } | undefined +>o5.x : { y: { z?: { w: boolean; }; }; } | undefined +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } | undefined o5.x?.y; ->o5.x?.y : { z?: { w: boolean; } | undefined; } | undefined ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->y : { z?: { w: boolean; } | undefined; } | undefined +>o5.x?.y : { z?: { w: boolean; }; } | undefined +>o5.x : { y: { z?: { w: boolean; }; }; } | undefined +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } | undefined +>y : { z?: { w: boolean; }; } | undefined o5.x?.y.z; >o5.x?.y.z : { w: boolean; } | undefined ->o5.x?.y : { z?: { w: boolean; } | undefined; } | undefined ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->y : { z?: { w: boolean; } | undefined; } | undefined +>o5.x?.y : { z?: { w: boolean; }; } | undefined +>o5.x : { y: { z?: { w: boolean; }; }; } | undefined +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } | undefined +>y : { z?: { w: boolean; }; } | undefined >z : { w: boolean; } | undefined o5.x?.y.z?.w; >o5.x?.y.z?.w : boolean | undefined >o5.x?.y.z : { w: boolean; } | undefined ->o5.x?.y : { z?: { w: boolean; } | undefined; } | undefined ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->y : { z?: { w: boolean; } | undefined; } | undefined +>o5.x?.y : { z?: { w: boolean; }; } | undefined +>o5.x : { y: { z?: { w: boolean; }; }; } | undefined +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } | undefined +>y : { z?: { w: boolean; }; } | undefined >z : { w: boolean; } | undefined >w : boolean | undefined o5.x.y; ->o5.x.y : { z?: { w: boolean; } | undefined; } ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->y : { z?: { w: boolean; } | undefined; } +>o5.x.y : { z?: { w: boolean; }; } +>o5.x : { y: { z?: { w: boolean; }; }; } | undefined +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } | undefined +>y : { z?: { w: boolean; }; } o5.x.y.z.w; >o5.x.y.z.w : boolean >o5.x.y.z : { w: boolean; } | undefined ->o5.x.y : { z?: { w: boolean; } | undefined; } ->o5.x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->o5 : { x?: { y: { z?: { w: boolean; } | undefined; }; } | undefined; } ->x : { y: { z?: { w: boolean; } | undefined; }; } | undefined ->y : { z?: { w: boolean; } | undefined; } +>o5.x.y : { z?: { w: boolean; }; } +>o5.x : { y: { z?: { w: boolean; }; }; } | undefined +>o5 : { x?: { y: { z?: { w: boolean; }; }; }; } +>x : { y: { z?: { w: boolean; }; }; } | undefined +>y : { z?: { w: boolean; }; } >z : { w: boolean; } | undefined >w : boolean diff --git a/tests/baselines/reference/deleteChain.types b/tests/baselines/reference/deleteChain.types index 2e5f7fedd3135..a2f3f7ce4c36c 100644 --- a/tests/baselines/reference/deleteChain.types +++ b/tests/baselines/reference/deleteChain.types @@ -61,9 +61,9 @@ delete (o3.b?.c); >c : string | undefined declare const o4: { b?: { c: { d?: { e: string } } } }; ->o4 : { b?: { c: { d?: { e: string; };}; } | undefined; } +>o4 : { b?: { c: { d?: { e: string; }; };}; } >b : { c: { d?: { e: string; };}; } | undefined ->c : { d?: { e: string; } | undefined; } +>c : { d?: { e: string;}; } >d : { e: string; } | undefined >e : string @@ -71,11 +71,11 @@ delete o4.b?.c.d?.e; >delete o4.b?.c.d?.e : boolean >o4.b?.c.d?.e : string | undefined >o4.b?.c.d : { e: string; } | undefined ->o4.b?.c : { d?: { e: string; } | undefined; } | undefined ->o4.b : { c: { d?: { e: string; } | undefined; }; } | undefined ->o4 : { b?: { c: { d?: { e: string; } | undefined; }; } | undefined; } ->b : { c: { d?: { e: string; } | undefined; }; } | undefined ->c : { d?: { e: string; } | undefined; } | undefined +>o4.b?.c : { d?: { e: string; }; } | undefined +>o4.b : { c: { d?: { e: string; }; }; } | undefined +>o4 : { b?: { c: { d?: { e: string; }; }; }; } +>b : { c: { d?: { e: string; }; }; } | undefined +>c : { d?: { e: string; }; } | undefined >d : { e: string; } | undefined >e : string | undefined @@ -84,11 +84,11 @@ delete (o4.b?.c.d)?.e; >(o4.b?.c.d)?.e : string | undefined >(o4.b?.c.d) : { e: string; } | undefined >o4.b?.c.d : { e: string; } | undefined ->o4.b?.c : { d?: { e: string; } | undefined; } | undefined ->o4.b : { c: { d?: { e: string; } | undefined; }; } | undefined ->o4 : { b?: { c: { d?: { e: string; } | undefined; }; } | undefined; } ->b : { c: { d?: { e: string; } | undefined; }; } | undefined ->c : { d?: { e: string; } | undefined; } | undefined +>o4.b?.c : { d?: { e: string; }; } | undefined +>o4.b : { c: { d?: { e: string; }; }; } | undefined +>o4 : { b?: { c: { d?: { e: string; }; }; }; } +>b : { c: { d?: { e: string; }; }; } | undefined +>c : { d?: { e: string; }; } | undefined >d : { e: string; } | undefined >e : string | undefined @@ -97,18 +97,18 @@ delete (o4.b?.c.d?.e); >(o4.b?.c.d?.e) : string | undefined >o4.b?.c.d?.e : string | undefined >o4.b?.c.d : { e: string; } | undefined ->o4.b?.c : { d?: { e: string; } | undefined; } | undefined ->o4.b : { c: { d?: { e: string; } | undefined; }; } | undefined ->o4 : { b?: { c: { d?: { e: string; } | undefined; }; } | undefined; } ->b : { c: { d?: { e: string; } | undefined; }; } | undefined ->c : { d?: { e: string; } | undefined; } | undefined +>o4.b?.c : { d?: { e: string; }; } | undefined +>o4.b : { c: { d?: { e: string; }; }; } | undefined +>o4 : { b?: { c: { d?: { e: string; }; }; }; } +>b : { c: { d?: { e: string; }; }; } | undefined +>c : { d?: { e: string; }; } | undefined >d : { e: string; } | undefined >e : string | undefined declare const o5: { b?(): { c: { d?: { e: string } } } }; >o5 : { b?(): { c: { d?: { e: string; }; };}; } >b : (() => { c: { d?: { e: string; }; };}) | undefined ->c : { d?: { e: string; } | undefined; } +>c : { d?: { e: string;}; } >d : { e: string; } | undefined >e : string @@ -116,12 +116,12 @@ delete o5.b?.().c.d?.e; >delete o5.b?.().c.d?.e : boolean >o5.b?.().c.d?.e : string | undefined >o5.b?.().c.d : { e: string; } | undefined ->o5.b?.().c : { d?: { e: string; } | undefined; } | undefined ->o5.b?.() : { c: { d?: { e: string; } | undefined; }; } | undefined ->o5.b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined ->o5 : { b?(): { c: { d?: { e: string; } | undefined; }; }; } ->b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined ->c : { d?: { e: string; } | undefined; } | undefined +>o5.b?.().c : { d?: { e: string; }; } | undefined +>o5.b?.() : { c: { d?: { e: string; }; }; } | undefined +>o5.b : (() => { c: { d?: { e: string; }; }; }) | undefined +>o5 : { b?(): { c: { d?: { e: string; }; }; }; } +>b : (() => { c: { d?: { e: string; }; }; }) | undefined +>c : { d?: { e: string; }; } | undefined >d : { e: string; } | undefined >e : string | undefined @@ -130,19 +130,19 @@ delete (o5.b?.().c.d?.e); >(o5.b?.().c.d?.e) : string | undefined >o5.b?.().c.d?.e : string | undefined >o5.b?.().c.d : { e: string; } | undefined ->o5.b?.().c : { d?: { e: string; } | undefined; } | undefined ->o5.b?.() : { c: { d?: { e: string; } | undefined; }; } | undefined ->o5.b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined ->o5 : { b?(): { c: { d?: { e: string; } | undefined; }; }; } ->b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined ->c : { d?: { e: string; } | undefined; } | undefined +>o5.b?.().c : { d?: { e: string; }; } | undefined +>o5.b?.() : { c: { d?: { e: string; }; }; } | undefined +>o5.b : (() => { c: { d?: { e: string; }; }; }) | undefined +>o5 : { b?(): { c: { d?: { e: string; }; }; }; } +>b : (() => { c: { d?: { e: string; }; }; }) | undefined +>c : { d?: { e: string; }; } | undefined >d : { e: string; } | undefined >e : string | undefined declare const o6: { b?: { c: { d?: { e: string } } } }; ->o6 : { b?: { c: { d?: { e: string; };}; } | undefined; } +>o6 : { b?: { c: { d?: { e: string; }; };}; } >b : { c: { d?: { e: string; };}; } | undefined ->c : { d?: { e: string; } | undefined; } +>c : { d?: { e: string;}; } >d : { e: string; } | undefined >e : string @@ -150,10 +150,10 @@ delete o6.b?.['c'].d?.['e']; >delete o6.b?.['c'].d?.['e'] : boolean >o6.b?.['c'].d?.['e'] : string | undefined >o6.b?.['c'].d : { e: string; } | undefined ->o6.b?.['c'] : { d?: { e: string; } | undefined; } | undefined ->o6.b : { c: { d?: { e: string; } | undefined; }; } | undefined ->o6 : { b?: { c: { d?: { e: string; } | undefined; }; } | undefined; } ->b : { c: { d?: { e: string; } | undefined; }; } | undefined +>o6.b?.['c'] : { d?: { e: string; }; } | undefined +>o6.b : { c: { d?: { e: string; }; }; } | undefined +>o6 : { b?: { c: { d?: { e: string; }; }; }; } +>b : { c: { d?: { e: string; }; }; } | undefined >'c' : "c" >d : { e: string; } | undefined >'e' : "e" @@ -163,10 +163,10 @@ delete (o6.b?.['c'].d?.['e']); >(o6.b?.['c'].d?.['e']) : string | undefined >o6.b?.['c'].d?.['e'] : string | undefined >o6.b?.['c'].d : { e: string; } | undefined ->o6.b?.['c'] : { d?: { e: string; } | undefined; } | undefined ->o6.b : { c: { d?: { e: string; } | undefined; }; } | undefined ->o6 : { b?: { c: { d?: { e: string; } | undefined; }; } | undefined; } ->b : { c: { d?: { e: string; } | undefined; }; } | undefined +>o6.b?.['c'] : { d?: { e: string; }; } | undefined +>o6.b : { c: { d?: { e: string; }; }; } | undefined +>o6 : { b?: { c: { d?: { e: string; }; }; }; } +>b : { c: { d?: { e: string; }; }; } | undefined >'c' : "c" >d : { e: string; } | undefined >'e' : "e" diff --git a/tests/baselines/reference/destructuringControlFlow.types b/tests/baselines/reference/destructuringControlFlow.types index 02deb39200688..6c04cfd193c5a 100644 --- a/tests/baselines/reference/destructuringControlFlow.types +++ b/tests/baselines/reference/destructuringControlFlow.types @@ -1,29 +1,29 @@ === tests/cases/conformance/es6/destructuring/destructuringControlFlow.ts === function f1(obj: { a?: string }) { >f1 : (obj: { a?: string;}) => void ->obj : { a?: string | undefined; } +>obj : { a?: string; } >a : string | undefined if (obj.a) { >obj.a : string | undefined ->obj : { a?: string | undefined; } +>obj : { a?: string; } >a : string | undefined obj = {}; >obj = {} : {} ->obj : { a?: string | undefined; } +>obj : { a?: string; } >{} : {} let a1 = obj["a"]; // string | undefined >a1 : string | undefined >obj["a"] : string | undefined ->obj : { a?: string | undefined; } +>obj : { a?: string; } >"a" : "a" let a2 = obj.a; // string | undefined >a2 : string | undefined >obj.a : string | undefined ->obj : { a?: string | undefined; } +>obj : { a?: string; } >a : string | undefined } } @@ -96,31 +96,31 @@ function f2(obj: [number, string] | null[]) { function f3(obj: { a?: number, b?: string }) { >f3 : (obj: { a?: number; b?: string;}) => void ->obj : { a?: number | undefined; b?: string | undefined; } +>obj : { a?: number; b?: string; } >a : number | undefined >b : string | undefined if (obj.a && obj.b) { >obj.a && obj.b : string | 0 | undefined >obj.a : number | undefined ->obj : { a?: number | undefined; b?: string | undefined; } +>obj : { a?: number; b?: string; } >a : number | undefined >obj.b : string | undefined ->obj : { a?: number | undefined; b?: string | undefined; } +>obj : { a?: number; b?: string; } >b : string | undefined let { a, b } = obj; // number, string >a : number >b : string ->obj : { a?: number | undefined; b?: string | undefined; } +>obj : { a?: number; b?: string; } ({ a, b } = obj); ->({ a, b } = obj) : { a?: number | undefined; b?: string | undefined; } ->{ a, b } = obj : { a?: number | undefined; b?: string | undefined; } +>({ a, b } = obj) : { a?: number; b?: string; } +>{ a, b } = obj : { a?: number; b?: string; } >{ a, b } : { a: number; b: string; } >a : number >b : string ->obj : { a?: number | undefined; b?: string | undefined; } +>obj : { a?: number; b?: string; } } } diff --git a/tests/baselines/reference/elementAccessChain.types b/tests/baselines/reference/elementAccessChain.types index ccb7d97460464..681312b515cb6 100644 --- a/tests/baselines/reference/elementAccessChain.types +++ b/tests/baselines/reference/elementAccessChain.types @@ -47,19 +47,19 @@ o3.b?.["c"]; >"c" : "c" declare const o4: { b?: { c: { d?: { e: string } } } }; ->o4 : { b?: { c: { d?: { e: string; };}; } | undefined; } +>o4 : { b?: { c: { d?: { e: string; }; };}; } >b : { c: { d?: { e: string; };}; } | undefined ->c : { d?: { e: string; } | undefined; } +>c : { d?: { e: string;}; } >d : { e: string; } | undefined >e : string o4.b?.["c"].d?.e; >o4.b?.["c"].d?.e : string | undefined >o4.b?.["c"].d : { e: string; } | undefined ->o4.b?.["c"] : { d?: { e: string; } | undefined; } | undefined ->o4.b : { c: { d?: { e: string; } | undefined; }; } | undefined ->o4 : { b?: { c: { d?: { e: string; } | undefined; }; } | undefined; } ->b : { c: { d?: { e: string; } | undefined; }; } | undefined +>o4.b?.["c"] : { d?: { e: string; }; } | undefined +>o4.b : { c: { d?: { e: string; }; }; } | undefined +>o4 : { b?: { c: { d?: { e: string; }; }; }; } +>b : { c: { d?: { e: string; }; }; } | undefined >"c" : "c" >d : { e: string; } | undefined >e : string | undefined @@ -67,10 +67,10 @@ o4.b?.["c"].d?.e; o4.b?.["c"].d?.["e"]; >o4.b?.["c"].d?.["e"] : string | undefined >o4.b?.["c"].d : { e: string; } | undefined ->o4.b?.["c"] : { d?: { e: string; } | undefined; } | undefined ->o4.b : { c: { d?: { e: string; } | undefined; }; } | undefined ->o4 : { b?: { c: { d?: { e: string; } | undefined; }; } | undefined; } ->b : { c: { d?: { e: string; } | undefined; }; } | undefined +>o4.b?.["c"] : { d?: { e: string; }; } | undefined +>o4.b : { c: { d?: { e: string; }; }; } | undefined +>o4 : { b?: { c: { d?: { e: string; }; }; }; } +>b : { c: { d?: { e: string; }; }; } | undefined >"c" : "c" >d : { e: string; } | undefined >"e" : "e" @@ -78,18 +78,18 @@ o4.b?.["c"].d?.["e"]; declare const o5: { b?(): { c: { d?: { e: string } } } }; >o5 : { b?(): { c: { d?: { e: string; }; };}; } >b : (() => { c: { d?: { e: string; }; };}) | undefined ->c : { d?: { e: string; } | undefined; } +>c : { d?: { e: string;}; } >d : { e: string; } | undefined >e : string o5.b?.()["c"].d?.e; >o5.b?.()["c"].d?.e : string | undefined >o5.b?.()["c"].d : { e: string; } | undefined ->o5.b?.()["c"] : { d?: { e: string; } | undefined; } | undefined ->o5.b?.() : { c: { d?: { e: string; } | undefined; }; } | undefined ->o5.b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined ->o5 : { b?(): { c: { d?: { e: string; } | undefined; }; }; } ->b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined +>o5.b?.()["c"] : { d?: { e: string; }; } | undefined +>o5.b?.() : { c: { d?: { e: string; }; }; } | undefined +>o5.b : (() => { c: { d?: { e: string; }; }; }) | undefined +>o5 : { b?(): { c: { d?: { e: string; }; }; }; } +>b : (() => { c: { d?: { e: string; }; }; }) | undefined >"c" : "c" >d : { e: string; } | undefined >e : string | undefined @@ -97,11 +97,11 @@ o5.b?.()["c"].d?.e; o5.b?.()["c"].d?.["e"]; >o5.b?.()["c"].d?.["e"] : string | undefined >o5.b?.()["c"].d : { e: string; } | undefined ->o5.b?.()["c"] : { d?: { e: string; } | undefined; } | undefined ->o5.b?.() : { c: { d?: { e: string; } | undefined; }; } | undefined ->o5.b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined ->o5 : { b?(): { c: { d?: { e: string; } | undefined; }; }; } ->b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined +>o5.b?.()["c"] : { d?: { e: string; }; } | undefined +>o5.b?.() : { c: { d?: { e: string; }; }; } | undefined +>o5.b : (() => { c: { d?: { e: string; }; }; }) | undefined +>o5 : { b?(): { c: { d?: { e: string; }; }; }; } +>b : (() => { c: { d?: { e: string; }; }; }) | undefined >"c" : "c" >d : { e: string; } | undefined >"e" : "e" @@ -109,10 +109,10 @@ o5.b?.()["c"].d?.["e"]; o5["b"]?.()["c"].d?.e; >o5["b"]?.()["c"].d?.e : string | undefined >o5["b"]?.()["c"].d : { e: string; } | undefined ->o5["b"]?.()["c"] : { d?: { e: string; } | undefined; } | undefined ->o5["b"]?.() : { c: { d?: { e: string; } | undefined; }; } | undefined ->o5["b"] : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined ->o5 : { b?(): { c: { d?: { e: string; } | undefined; }; }; } +>o5["b"]?.()["c"] : { d?: { e: string; }; } | undefined +>o5["b"]?.() : { c: { d?: { e: string; }; }; } | undefined +>o5["b"] : (() => { c: { d?: { e: string; }; }; }) | undefined +>o5 : { b?(): { c: { d?: { e: string; }; }; }; } >"b" : "b" >"c" : "c" >d : { e: string; } | undefined @@ -121,10 +121,10 @@ o5["b"]?.()["c"].d?.e; o5["b"]?.()["c"].d?.["e"]; >o5["b"]?.()["c"].d?.["e"] : string | undefined >o5["b"]?.()["c"].d : { e: string; } | undefined ->o5["b"]?.()["c"] : { d?: { e: string; } | undefined; } | undefined ->o5["b"]?.() : { c: { d?: { e: string; } | undefined; }; } | undefined ->o5["b"] : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined ->o5 : { b?(): { c: { d?: { e: string; } | undefined; }; }; } +>o5["b"]?.()["c"] : { d?: { e: string; }; } | undefined +>o5["b"]?.() : { c: { d?: { e: string; }; }; } | undefined +>o5["b"] : (() => { c: { d?: { e: string; }; }; }) | undefined +>o5 : { b?(): { c: { d?: { e: string; }; }; }; } >"b" : "b" >"c" : "c" >d : { e: string; } | undefined diff --git a/tests/baselines/reference/homomorphicMappedTypeIntersectionAssignability.types b/tests/baselines/reference/homomorphicMappedTypeIntersectionAssignability.types index f89f132dcc875..bf10a7f1585d1 100644 --- a/tests/baselines/reference/homomorphicMappedTypeIntersectionAssignability.types +++ b/tests/baselines/reference/homomorphicMappedTypeIntersectionAssignability.types @@ -3,7 +3,7 @@ function f( >f : (a: { weak?: string;} & Readonly & { name: "ok";}, b: Readonly, c: Readonly & { name: string;}) => void a: { weak?: string } & Readonly & { name: "ok" }, ->a : { weak?: string | undefined; } & Readonly & { name: "ok"; } +>a : { weak?: string; } & Readonly & { name: "ok"; } >weak : string | undefined >name : "ok" @@ -16,13 +16,13 @@ function f( >name : string c = a; // Works ->c = a : { weak?: string | undefined; } & Readonly & { name: "ok"; } +>c = a : { weak?: string; } & Readonly & { name: "ok"; } >c : Readonly & { name: string; } ->a : { weak?: string | undefined; } & Readonly & { name: "ok"; } +>a : { weak?: string; } & Readonly & { name: "ok"; } b = a; // Should also work ->b = a : { weak?: string | undefined; } & Readonly & { name: "ok"; } +>b = a : { weak?: string; } & Readonly & { name: "ok"; } >b : Readonly ->a : { weak?: string | undefined; } & Readonly & { name: "ok"; } +>a : { weak?: string; } & Readonly & { name: "ok"; } } diff --git a/tests/baselines/reference/inferenceOptionalPropertiesToIndexSignatures.types b/tests/baselines/reference/inferenceOptionalPropertiesToIndexSignatures.types index b707b156b2ea2..8c5ce88ac26f9 100644 --- a/tests/baselines/reference/inferenceOptionalPropertiesToIndexSignatures.types +++ b/tests/baselines/reference/inferenceOptionalPropertiesToIndexSignatures.types @@ -15,7 +15,7 @@ declare const x2: { a: string, b: number | undefined }; >b : number | undefined declare const x3: { a: string, b?: number }; ->x3 : { a: string; b?: number | undefined; } +>x3 : { a: string; b?: number; } >a : string >b : number | undefined @@ -40,7 +40,7 @@ let a3 = foo(x3); // string | number >a3 : string | number >foo(x3) : string | number >foo : (obj: { [x: string]: T; }) => T ->x3 : { a: string; b?: number | undefined; } +>x3 : { a: string; b?: number; } let a4 = foo(x4); // string | number >a4 : string | number @@ -63,8 +63,8 @@ const param2 = Math.random() < 0.5 ? 'value2' : null; >null : null const obj = { ->obj : { param2?: string | undefined; param1: string; } ->{ param1: 'value1', ...(param2 ? {param2} : {})} : { param2?: string | undefined; param1: string; } +>obj : { param2?: string; param1: string; } +>{ param1: 'value1', ...(param2 ? {param2} : {})} : { param2?: string; param1: string; } param1: 'value1', >param1 : string @@ -90,7 +90,7 @@ const query = Object.entries(obj).map( >Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor >entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } ->obj : { param2?: string | undefined; param1: string; } +>obj : { param2?: string; param1: string; } >map : (callbackfn: (value: [string, string], index: number, array: [string, string][]) => U, thisArg?: any) => U[] ([k, v]) => `${k}=${encodeURIComponent(v)}` diff --git a/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.types b/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.types index 5035da7bcef17..f6eb1f4f8107b 100644 --- a/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.types +++ b/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.types @@ -1,6 +1,6 @@ === tests/cases/compiler/index.d.ts === export declare function foo({a}?: { ->foo : ({ a }?: { a?: string | undefined; } | undefined) => void +>foo : ({ a }?: { a?: string; } | undefined) => void >a : string | undefined a?: string; diff --git a/tests/baselines/reference/instantiateContextualTypes.types b/tests/baselines/reference/instantiateContextualTypes.types index ff6154c78589c..902114916c494 100644 --- a/tests/baselines/reference/instantiateContextualTypes.types +++ b/tests/baselines/reference/instantiateContextualTypes.types @@ -221,7 +221,7 @@ interface ComponentClass

{ } type CreateElementChildren

= ->CreateElementChildren : P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown +>CreateElementChildren : P extends { children?: infer C; } ? C extends any[] ? C : C[] : unknown P extends { children?: infer C } >children : C | undefined @@ -232,24 +232,24 @@ type CreateElementChildren

= : unknown; declare function createElement

( ->createElement :

(type: ComponentClass

, ...children: P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown) => any +>createElement :

(type: ComponentClass

, ...children: P extends { children?: infer C; } ? C extends any[] ? C : C[] : unknown) => any type: ComponentClass

, >type : ComponentClass

...children: CreateElementChildren

->children : P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown +>children : P extends { children?: infer C; } ? C extends any[] ? C : C[] : unknown ): any; declare function createElement2

( ->createElement2 :

(type: ComponentClass

, child: P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown) => any +>createElement2 :

(type: ComponentClass

, child: P extends { children?: infer C; } ? C extends any[] ? C : C[] : unknown) => any type: ComponentClass

, >type : ComponentClass

child: CreateElementChildren

->child : P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown +>child : P extends { children?: infer C; } ? C extends any[] ? C : C[] : unknown ): any; @@ -261,7 +261,7 @@ class InferFunctionTypes extends Component<{children: (foo: number) => string}> createElement(InferFunctionTypes, (foo) => "" + foo); >createElement(InferFunctionTypes, (foo) => "" + foo) : any ->createElement :

(type: ComponentClass

, ...children: P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown) => any +>createElement :

(type: ComponentClass

, ...children: P extends { children?: infer C; } ? C extends any[] ? C : C[] : unknown) => any >InferFunctionTypes : typeof InferFunctionTypes >(foo) => "" + foo : (foo: number) => string >foo : number @@ -271,7 +271,7 @@ createElement(InferFunctionTypes, (foo) => "" + foo); createElement2(InferFunctionTypes, [(foo) => "" + foo]); >createElement2(InferFunctionTypes, [(foo) => "" + foo]) : any ->createElement2 :

(type: ComponentClass

, child: P extends { children?: infer C | undefined; } ? C extends any[] ? C : C[] : unknown) => any +>createElement2 :

(type: ComponentClass

, child: P extends { children?: infer C; } ? C extends any[] ? C : C[] : unknown) => any >InferFunctionTypes : typeof InferFunctionTypes >[(foo) => "" + foo] : ((foo: number) => string)[] >(foo) => "" + foo : (foo: number) => string diff --git a/tests/baselines/reference/intersectionPropertyCheck.errors.txt b/tests/baselines/reference/intersectionPropertyCheck.errors.txt index 7c74c3512eaf1..494832fec8123 100644 --- a/tests/baselines/reference/intersectionPropertyCheck.errors.txt +++ b/tests/baselines/reference/intersectionPropertyCheck.errors.txt @@ -1,12 +1,12 @@ tests/cases/compiler/intersectionPropertyCheck.ts(1,68): error TS2322: Type '{ x: string; y: number; }' is not assignable to type '{ x: string; }'. Object literal may only specify known properties, and 'y' does not exist in type '{ x: string; }'. -tests/cases/compiler/intersectionPropertyCheck.ts(4,5): error TS2322: Type '{ a: { y: string; }; }' is not assignable to type '{ a?: { x?: number | undefined; } | undefined; } & { c?: string | undefined; }'. +tests/cases/compiler/intersectionPropertyCheck.ts(4,5): error TS2322: Type '{ a: { y: string; }; }' is not assignable to type '{ a?: { x?: number; }; } & { c?: string; }'. Types of property 'a' are incompatible. - Type '{ y: string; }' has no properties in common with type '{ x?: number | undefined; }'. -tests/cases/compiler/intersectionPropertyCheck.ts(7,3): error TS2322: Type 'T & { a: boolean; }' is not assignable to type '{ a?: string | undefined; }'. + Type '{ y: string; }' has no properties in common with type '{ x?: number; }'. +tests/cases/compiler/intersectionPropertyCheck.ts(7,3): error TS2322: Type 'T & { a: boolean; }' is not assignable to type '{ a?: string; }'. Types of property 'a' are incompatible. - Type 'boolean' is not assignable to type 'string | undefined'. -tests/cases/compiler/intersectionPropertyCheck.ts(17,22): error TS2322: Type 'true' is not assignable to type 'string[] | undefined'. + Type 'boolean' is not assignable to type 'string'. +tests/cases/compiler/intersectionPropertyCheck.ts(17,22): error TS2322: Type 'boolean' is not assignable to type 'string[]'. ==== tests/cases/compiler/intersectionPropertyCheck.ts (4 errors) ==== @@ -19,16 +19,16 @@ tests/cases/compiler/intersectionPropertyCheck.ts(17,22): error TS2322: Type 'tr declare let wrong: { a: { y: string } }; let weak: { a?: { x?: number } } & { c?: string } = wrong; // Nested weak object type ~~~~ -!!! error TS2322: Type '{ a: { y: string; }; }' is not assignable to type '{ a?: { x?: number | undefined; } | undefined; } & { c?: string | undefined; }'. +!!! error TS2322: Type '{ a: { y: string; }; }' is not assignable to type '{ a?: { x?: number; }; } & { c?: string; }'. !!! error TS2322: Types of property 'a' are incompatible. -!!! error TS2322: Type '{ y: string; }' has no properties in common with type '{ x?: number | undefined; }'. +!!! error TS2322: Type '{ y: string; }' has no properties in common with type '{ x?: number; }'. function foo(x: { a?: string }, y: T & { a: boolean }) { x = y; // Mismatched property in source intersection ~ -!!! error TS2322: Type 'T & { a: boolean; }' is not assignable to type '{ a?: string | undefined; }'. +!!! error TS2322: Type 'T & { a: boolean; }' is not assignable to type '{ a?: string; }'. !!! error TS2322: Types of property 'a' are incompatible. -!!! error TS2322: Type 'boolean' is not assignable to type 'string | undefined'. +!!! error TS2322: Type 'boolean' is not assignable to type 'string'. } // Repro from #36637 @@ -40,7 +40,7 @@ tests/cases/compiler/intersectionPropertyCheck.ts(17,22): error TS2322: Type 'tr function test(value: T): Test { return { ...value, hi: true } ~~ -!!! error TS2322: Type 'true' is not assignable to type 'string[] | undefined'. +!!! error TS2322: Type 'boolean' is not assignable to type 'string[]'. !!! related TS6500 tests/cases/compiler/intersectionPropertyCheck.ts:13:12: The expected type comes from property 'hi' which is declared here on type 'Test' } \ No newline at end of file diff --git a/tests/baselines/reference/intersectionPropertyCheck.types b/tests/baselines/reference/intersectionPropertyCheck.types index 515d5009732fd..5b37490ea88cf 100644 --- a/tests/baselines/reference/intersectionPropertyCheck.types +++ b/tests/baselines/reference/intersectionPropertyCheck.types @@ -20,22 +20,22 @@ declare let wrong: { a: { y: string } }; >y : string let weak: { a?: { x?: number } } & { c?: string } = wrong; // Nested weak object type ->weak : { a?: { x?: number | undefined; } | undefined; } & { c?: string | undefined; } ->a : { x?: number | undefined; } | undefined +>weak : { a?: { x?: number;}; } & { c?: string; } +>a : { x?: number; } | undefined >x : number | undefined >c : string | undefined >wrong : { a: { y: string; }; } function foo(x: { a?: string }, y: T & { a: boolean }) { >foo : (x: { a?: string;}, y: T & { a: boolean;}) => void ->x : { a?: string | undefined; } +>x : { a?: string; } >a : string | undefined >y : T & { a: boolean; } >a : boolean x = y; // Mismatched property in source intersection >x = y : T & { a: boolean; } ->x : { a?: string | undefined; } +>x : { a?: string; } >y : T & { a: boolean; } } diff --git a/tests/baselines/reference/intersectionsAndOptionalProperties.errors.txt b/tests/baselines/reference/intersectionsAndOptionalProperties.errors.txt index faa8b067b1ac3..2bd15c04d42d6 100644 --- a/tests/baselines/reference/intersectionsAndOptionalProperties.errors.txt +++ b/tests/baselines/reference/intersectionsAndOptionalProperties.errors.txt @@ -1,13 +1,13 @@ -tests/cases/compiler/intersectionsAndOptionalProperties.ts(5,1): error TS2322: Type '{ a: null; b: string; }' is not assignable to type '{ a?: number | undefined; b: string; }'. +tests/cases/compiler/intersectionsAndOptionalProperties.ts(5,1): error TS2322: Type '{ a: null; b: string; }' is not assignable to type '{ a?: number; b: string; }'. Types of property 'a' are incompatible. - Type 'null' is not assignable to type 'number | undefined'. -tests/cases/compiler/intersectionsAndOptionalProperties.ts(6,1): error TS2322: Type '{ a: null; } & { b: string; }' is not assignable to type '{ a?: number | undefined; b: string; }'. + Type 'null' is not assignable to type 'number'. +tests/cases/compiler/intersectionsAndOptionalProperties.ts(6,1): error TS2322: Type '{ a: null; } & { b: string; }' is not assignable to type '{ a?: number; b: string; }'. Types of property 'a' are incompatible. - Type 'null' is not assignable to type 'number | undefined'. + Type 'null' is not assignable to type 'number'. tests/cases/compiler/intersectionsAndOptionalProperties.ts(19,5): error TS2322: Type 'From' is not assignable to type 'To'. Types of property 'field' are incompatible. - Type 'null' is not assignable to type 'number | undefined'. -tests/cases/compiler/intersectionsAndOptionalProperties.ts(20,5): error TS2322: Type 'null' is not assignable to type 'number | undefined'. + Type 'null' is not assignable to type 'number'. +tests/cases/compiler/intersectionsAndOptionalProperties.ts(20,5): error TS2322: Type 'null' is not assignable to type 'number'. ==== tests/cases/compiler/intersectionsAndOptionalProperties.ts (4 errors) ==== @@ -17,14 +17,14 @@ tests/cases/compiler/intersectionsAndOptionalProperties.ts(20,5): error TS2322: x = y; // Error ~ -!!! error TS2322: Type '{ a: null; b: string; }' is not assignable to type '{ a?: number | undefined; b: string; }'. +!!! error TS2322: Type '{ a: null; b: string; }' is not assignable to type '{ a?: number; b: string; }'. !!! error TS2322: Types of property 'a' are incompatible. -!!! error TS2322: Type 'null' is not assignable to type 'number | undefined'. +!!! error TS2322: Type 'null' is not assignable to type 'number'. x = z; // Error ~ -!!! error TS2322: Type '{ a: null; } & { b: string; }' is not assignable to type '{ a?: number | undefined; b: string; }'. +!!! error TS2322: Type '{ a: null; } & { b: string; }' is not assignable to type '{ a?: number; b: string; }'. !!! error TS2322: Types of property 'a' are incompatible. -!!! error TS2322: Type 'null' is not assignable to type 'number | undefined'. +!!! error TS2322: Type 'null' is not assignable to type 'number'. // Repro from #36604 @@ -41,10 +41,10 @@ tests/cases/compiler/intersectionsAndOptionalProperties.ts(20,5): error TS2322: ~ !!! error TS2322: Type 'From' is not assignable to type 'To'. !!! error TS2322: Types of property 'field' are incompatible. -!!! error TS2322: Type 'null' is not assignable to type 'number | undefined'. +!!! error TS2322: Type 'null' is not assignable to type 'number'. x.field = v.field; // Error ~~~~~~~ -!!! error TS2322: Type 'null' is not assignable to type 'number | undefined'. +!!! error TS2322: Type 'null' is not assignable to type 'number'. } // Repro from #38348 diff --git a/tests/baselines/reference/intersectionsAndOptionalProperties.types b/tests/baselines/reference/intersectionsAndOptionalProperties.types index 98bc85c7e4299..655cdc513839f 100644 --- a/tests/baselines/reference/intersectionsAndOptionalProperties.types +++ b/tests/baselines/reference/intersectionsAndOptionalProperties.types @@ -1,6 +1,6 @@ === tests/cases/compiler/intersectionsAndOptionalProperties.ts === declare let x: { a?: number, b: string }; ->x : { a?: number | undefined; b: string; } +>x : { a?: number; b: string; } >a : number | undefined >b : string @@ -18,12 +18,12 @@ declare let z: { a: null } & { b: string }; x = y; // Error >x = y : { a: null; b: string; } ->x : { a?: number | undefined; b: string; } +>x : { a?: number; b: string; } >y : { a: null; b: string; } x = z; // Error >x = z : { a: null; } & { b: string; } ->x : { a?: number | undefined; b: string; } +>x : { a?: number; b: string; } >z : { a: null; } & { b: string; } // Repro from #36604 @@ -55,9 +55,9 @@ function foo(v: From) { x.field = v.field; // Error >x.field = v.field : null ->x.field : number | undefined +>x.field : number >x : To ->field : number | undefined +>field : number >v.field : null >v : From >field : null diff --git a/tests/baselines/reference/jsDeclarationsReactComponents.types b/tests/baselines/reference/jsDeclarationsReactComponents.types index 4934a173b935b..17a63894fddf4 100644 --- a/tests/baselines/reference/jsDeclarationsReactComponents.types +++ b/tests/baselines/reference/jsDeclarationsReactComponents.types @@ -61,7 +61,7 @@ import React from "react"; */ const TabbedShowLayout = () => { >TabbedShowLayout : React.SFC<{}> ->() => { return (

ok
);} : { (): JSX.Element; defaultProps: Partial<{}> | undefined; } +>() => { return (
ok
);} : { (): JSX.Element; defaultProps: Partial<{}>; } return ( >(
ok
) : JSX.Element @@ -81,9 +81,9 @@ const TabbedShowLayout = () => { TabbedShowLayout.defaultProps = { >TabbedShowLayout.defaultProps = { tabs: "default value"} : { tabs: string; } ->TabbedShowLayout.defaultProps : Partial<{}> | undefined +>TabbedShowLayout.defaultProps : Partial<{}> >TabbedShowLayout : React.SFC<{}> ->defaultProps : Partial<{}> | undefined +>defaultProps : Partial<{}> >{ tabs: "default value"} : { tabs: string; } tabs: "default value" diff --git a/tests/baselines/reference/jsxComplexSignatureHasApplicabilityError.errors.txt b/tests/baselines/reference/jsxComplexSignatureHasApplicabilityError.errors.txt new file mode 100644 index 0000000000000..a10ae139e0381 --- /dev/null +++ b/tests/baselines/reference/jsxComplexSignatureHasApplicabilityError.errors.txt @@ -0,0 +1,626 @@ +tests/cases/compiler/jsxComplexSignatureHasApplicabilityError.tsx(31,17): error TS2769: No overload matches this call. + Overload 1 of 2, '(props: Readonly>>): ReactSelectClass>', gave the following error. + Type 'ExtractValueType | Option> | undefined' is not assignable to type 'string | number | boolean | string[] | number[] | Option> | Options>'. + Type 'undefined' is not assignable to type 'string | number | boolean | string[] | number[] | Option> | Options>'. + Overload 2 of 2, '(props: ReactSelectProps>, context?: any): ReactSelectClass>', gave the following error. + Type 'ExtractValueType | Option> | undefined' is not assignable to type 'string | number | boolean | string[] | number[] | Option> | Options>'. + + +==== tests/cases/compiler/jsxComplexSignatureHasApplicabilityError.tsx (1 errors) ==== + /// + + import * as React from "react"; + + + interface Props { + value?: Option | T; + onChange?(value: Option | undefined): void; + } + + type ExtractValueType = T extends ReactSelectProps ? U : never; + + export type ReactSingleSelectProps< + WrappedProps extends ReactSelectProps + > = Overwrite< + Omit, + Props> + >; + + export function createReactSingleSelect< + WrappedProps extends ReactSelectProps + >( + WrappedComponent: React.ComponentType + ): React.ComponentType> { + return (props) => { + return ( + > + {...props} + multi={false} + autosize={false} + value={props.value} + ~~~~~ +!!! error TS2769: No overload matches this call. +!!! error TS2769: Overload 1 of 2, '(props: Readonly>>): ReactSelectClass>', gave the following error. +!!! error TS2769: Type 'ExtractValueType | Option> | undefined' is not assignable to type 'string | number | boolean | string[] | number[] | Option> | Options>'. +!!! error TS2769: Type 'undefined' is not assignable to type 'string | number | boolean | string[] | number[] | Option> | Options>'. +!!! error TS2769: Overload 2 of 2, '(props: ReactSelectProps>, context?: any): ReactSelectClass>', gave the following error. +!!! error TS2769: Type 'ExtractValueType | Option> | undefined' is not assignable to type 'string | number | boolean | string[] | number[] | Option> | Options>'. +!!! related TS6500 tests/cases/compiler/jsxComplexSignatureHasApplicabilityError.tsx:567:5: The expected type comes from property 'value' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes>> & Readonly<{ children?: ReactNode; }> & Readonly>>' +!!! related TS6500 tests/cases/compiler/jsxComplexSignatureHasApplicabilityError.tsx:567:5: The expected type comes from property 'value' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes>> & Readonly<{ children?: ReactNode; }> & Readonly>>' + onChange={(value) => { + if (props.onChange) { + props.onChange(value === null ? undefined : value); + } + }} + /> + ); + }; + } + + + // Copied from "type-zoo" version 3.4.0 + export type Omit = T extends any ? Pick> : never; + export type Overwrite = Omit & U; + + // Everything below here copied from "@types/react-select" version 1.3.4 + declare class ReactSelectClass extends React.Component> { + focus(): void; + setValue(value: Option): void; + } + + export type OptionComponentType = React.ComponentType>; + export type ValueComponentType = React.ComponentType>; + + export type HandlerRendererResult = JSX.Element | null | false; + + // Handlers + export type FocusOptionHandler = (option: Option) => void; + export type SelectValueHandler = (option: Option) => void; + export type ArrowRendererHandler = (props: ArrowRendererProps) => HandlerRendererResult; + export type ClearRendererHandler = () => HandlerRendererResult; + export type FilterOptionHandler = (option: Option, filter: string) => boolean; + export type FilterOptionsHandler = (options: Options, filter: string, currentValues: Options) => Options; + export type InputRendererHandler = (props: { [key: string]: any }) => HandlerRendererResult; + export type MenuRendererHandler = (props: MenuRendererProps) => HandlerRendererResult; + export type OnCloseHandler = () => void; + export type OnInputChangeHandler = (inputValue: string) => string; + export type OnInputKeyDownHandler = React.KeyboardEventHandler; + export type OnMenuScrollToBottomHandler = () => void; + export type OnOpenHandler = () => void; + export type OnFocusHandler = React.FocusEventHandler; + export type OnBlurHandler = React.FocusEventHandler; + export type OptionRendererHandler = (option: Option) => HandlerRendererResult; + export type ValueRendererHandler = (option: Option, index?: number) => HandlerRendererResult; + export type OnValueClickHandler = (option: Option, event: React.MouseEvent) => void; + export type IsOptionUniqueHandler = (arg: { option: Option, options: Options, labelKey: string, valueKey: string }) => boolean; + export type IsValidNewOptionHandler = (arg: { label: string }) => boolean; + export type NewOptionCreatorHandler = (arg: { label: string, labelKey: string, valueKey: string }) => Option; + export type PromptTextCreatorHandler = (filterText: string) => string; + export type ShouldKeyDownEventCreateNewOptionHandler = (arg: { keyCode: number }) => boolean; + + export type OnChangeSingleHandler = OnChangeHandler>; + export type OnChangeMultipleHandler = OnChangeHandler>; + export type OnChangeHandler | Options> = (newValue: TOption | null) => void; + export type OnNewOptionClickHandler = (option: Option) => void; + + export type LoadOptionsHandler = LoadOptionsAsyncHandler | LoadOptionsLegacyHandler; + export type LoadOptionsAsyncHandler = (input: string) => Promise>; + export type LoadOptionsLegacyHandler = (input: string, callback: (err: any, result: AutocompleteResult) => void) => void; + + export interface AutocompleteResult { + /** The search-results to be displayed */ + options: Options; + /** + * Should be set to true, if and only if a longer query with the same prefix + * would return a subset of the results + * If set to true, more specific queries will not be sent to the server. + */ + complete: boolean; + } + + export type Options = Array>; + + export interface Option { + /** Text for rendering */ + label?: string; + /** Value for searching */ + value?: TValue; + /** + * Allow this option to be cleared + * @default true + */ + clearableValue?: boolean; + /** + * Do not allow this option to be selected + * @default false + */ + disabled?: boolean; + /** + * In the event that a custom menuRenderer is provided, Option should be able + * to accept arbitrary key-value pairs. See react-virtualized-select. + */ + [property: string]: any; + } + + export type OptionValues = string | number | boolean; + + export interface MenuRendererProps { + /** + * The currently focused option; should be visible in the menu by default. + * default {} + */ + focusedOption: Option; + + /** + * Callback to focus a new option; receives the option as a parameter. + */ + focusOption: FocusOptionHandler; + + /** + * Option labels are accessible with this string key. + */ + labelKey: string; + + /** + * Ordered array of options to render. + */ + options: Options; + + /** + * Callback to select a new option; receives the option as a parameter. + */ + selectValue: SelectValueHandler; + + /** + * Array of currently selected options. + */ + valueArray: Options; + + /** + * Callback to remove selection from option; receives the option as a parameter. + */ + removeValue: SelectValueHandler; + + /** + * function which returns a custom way to render the options in the menu + */ + optionRenderer: OptionRendererHandler; + } + + export interface OptionComponentProps { + /** + * Classname(s) to apply to the option component. + */ + className?: string; + + /** + * Currently focused option. + */ + focusOption?: Option; + + inputValue?: string; + instancePrefix?: string; + + /** + * True if this option is disabled. + */ + isDisabled?: boolean; + + /** + * True if this option is focused. + */ + isFocused?: boolean; + + /** + * True if this option is selected. + */ + isSelected?: boolean; + + /** + * Callback to be invoked when this option is focused. + */ + onFocus?: (option: Option, event: any) => void; + + /** + * Callback to be invoked when this option is selected. + */ + onSelect?: (option: Option, event: any) => void; + + /** + * Option to be rendered by this component. + */ + option: Option; + + /** + * Index of the option being rendered in the list + */ + optionIndex?: number; + + /** + * Callback to invoke when removing an option from a multi-selection. (Not necessarily the one + * being rendered) + */ + removeValue?: (value: TValue | TValue[]) => void; + + /** + * Callback to invoke to select an option. (Not necessarily the one being rendered) + */ + selectValue?: (value: TValue | TValue[]) => void; + } + + export interface ArrowRendererProps { + /** + * Arrow mouse down event handler. + */ + onMouseDown: React.MouseEventHandler; + + /** + * whether the Select is open or not. + */ + isOpen: boolean; + } + + export interface ValueComponentProps { + disabled: ReactSelectProps['disabled']; + id: string; + instancePrefix: string; + onClick: OnValueClickHandler | null; + onRemove?: SelectValueHandler; + placeholder: ReactSelectProps['placeholder']; + value: Option; + values?: Array>; + } + + export interface ReactSelectProps extends React.Props> { + /** + * text to display when `allowCreate` is true. + * @default 'Add "{label}"?' + */ + addLabelText?: string; + /** + * renders a custom drop-down arrow to be shown in the right-hand side of the select. + * @default undefined + */ + arrowRenderer?: ArrowRendererHandler | null; + /** + * blurs the input element after a selection has been made. Handy for lowering the keyboard on mobile devices. + * @default false + */ + autoBlur?: boolean; + /** + * autofocus the component on mount + * @deprecated. Use autoFocus instead + * @default false + */ + autofocus?: boolean; + /** + * autofocus the component on mount + * @default false + */ + autoFocus?: boolean; + /** + * If enabled, the input will expand as the length of its value increases + */ + autosize?: boolean; + /** + * whether pressing backspace removes the last item when there is no input value + * @default true + */ + backspaceRemoves?: boolean; + /** + * Message to use for screenreaders to press backspace to remove the current item + * {label} is replaced with the item label + * @default "Press backspace to remove..." + */ + backspaceToRemoveMessage?: string; + /** + * CSS className for the outer element + */ + className?: string; + /** + * Prefix prepended to element default className if no className is defined + */ + classNamePrefix?: string; + /** + * title for the "clear" control when `multi` is true + * @default "Clear all" + */ + clearAllText?: string; + /** + * Renders a custom clear to be shown in the right-hand side of the select when clearable true + * @default undefined + */ + clearRenderer?: ClearRendererHandler; + /** + * title for the "clear" control + * @default "Clear value" + */ + clearValueText?: string; + /** + * whether to close the menu when a value is selected + * @default true + */ + closeOnSelect?: boolean; + /** + * whether it is possible to reset value. if enabled, an X button will appear at the right side. + * @default true + */ + clearable?: boolean; + /** + * whether backspace removes an item if there is no text input + * @default true + */ + deleteRemoves?: boolean; + /** + * delimiter to use to join multiple values + * @default "," + */ + delimiter?: string; + /** + * whether the Select is disabled or not + * @default false + */ + disabled?: boolean; + /** + * whether escape clears the value when the menu is closed + * @default true + */ + escapeClearsValue?: boolean; + /** + * method to filter a single option + */ + filterOption?: FilterOptionHandler; + /** + * method to filter the options array + */ + filterOptions?: FilterOptionsHandler; + /** + * id for the underlying HTML input element + * @default undefined + */ + id?: string; + /** + * whether to strip diacritics when filtering + * @default true + */ + ignoreAccents?: boolean; + /** + * whether to perform case-insensitive filtering + * @default true + */ + ignoreCase?: boolean; + /** + * custom attributes for the Input (in the Select-control) e.g: {'data-foo': 'bar'} + * @default {} + */ + inputProps?: { [key: string]: any }; + /** + * renders a custom input + */ + inputRenderer?: InputRendererHandler; + /** + * allows for synchronization of component id's on server and client. + * @see https://github.com/JedWatson/react-select/pull/1105 + */ + instanceId?: string; + /** + * whether the Select is loading externally or not (such as options being loaded). + * if true, a loading spinner will be shown at the right side. + * @default false + */ + isLoading?: boolean; + /** + * (legacy mode) joins multiple values into a single form field with the delimiter + * @default false + */ + joinValues?: boolean; + /** + * the option property to use for the label + * @default "label" + */ + labelKey?: string; + /** + * (any, start) match the start or entire string when filtering + * @default "any" + */ + matchPos?: string; + /** + * (any, label, value) which option property to filter on + * @default "any" + */ + matchProp?: string; + /** + * buffer of px between the base of the dropdown and the viewport to shift if menu doesnt fit in viewport + * @default 0 + */ + menuBuffer?: number; + /** + * optional style to apply to the menu container + */ + menuContainerStyle?: React.CSSProperties; + /** + * renders a custom menu with options + */ + menuRenderer?: MenuRendererHandler; + /** + * optional style to apply to the menu + */ + menuStyle?: React.CSSProperties; + /** + * multi-value input + * @default false + */ + multi?: boolean; + /** + * field name, for hidden `` tag + */ + name?: string; + /** + * placeholder displayed when there are no matching search results or a falsy value to hide it + * @default "No results found" + */ + noResultsText?: string | JSX.Element; + /** + * onBlur handler: function (event) {} + */ + onBlur?: OnBlurHandler; + /** + * whether to clear input on blur or not + * @default true + */ + onBlurResetsInput?: boolean; + /** + * whether the input value should be reset when options are selected. + * Also input value will be set to empty if 'onSelectResetsInput=true' and + * Select will get new value that not equal previous value. + * @default true + */ + onSelectResetsInput?: boolean; + /** + * whether to clear input when closing the menu through the arrow + * @default true + */ + onCloseResetsInput?: boolean; + /** + * onChange handler: function (newValue) {} + */ + onChange?: OnChangeHandler; + /** + * fires when the menu is closed + */ + onClose?: OnCloseHandler; + /** + * onFocus handler: function (event) {} + */ + onFocus?: OnFocusHandler; + /** + * onInputChange handler: function (inputValue) {} + */ + onInputChange?: OnInputChangeHandler; + /** + * onInputKeyDown handler: function (keyboardEvent) {} + */ + onInputKeyDown?: OnInputKeyDownHandler; + /** + * fires when the menu is scrolled to the bottom; can be used to paginate options + */ + onMenuScrollToBottom?: OnMenuScrollToBottomHandler; + /** + * fires when the menu is opened + */ + onOpen?: OnOpenHandler; + /** + * boolean to enable opening dropdown when focused + * @default false + */ + openOnClick?: boolean; + /** + * open the options menu when the input gets focus (requires searchable = true) + * @default true + */ + openOnFocus?: boolean; + /** + * className to add to each option component + */ + optionClassName?: string; + /** + * option component to render in dropdown + */ + optionComponent?: OptionComponentType; + /** + * function which returns a custom way to render the options in the menu + */ + optionRenderer?: OptionRendererHandler; + /** + * array of Select options + * @default false + */ + options?: Options; + /** + * number of options to jump when using page up/down keys + * @default 5 + */ + pageSize?: number; + /** + * field placeholder, displayed when there's no value + * @default "Select..." + */ + placeholder?: string | JSX.Element; + /** + * whether the selected option is removed from the dropdown on multi selects + * @default true + */ + removeSelected?: boolean; + /** + * applies HTML5 required attribute when needed + * @default false + */ + required?: boolean; + /** + * value to use when you clear the control + */ + resetValue?: any; + /** + * use react-select in right-to-left direction + * @default false + */ + rtl?: boolean; + /** + * whether the viewport will shift to display the entire menu when engaged + * @default true + */ + scrollMenuIntoView?: boolean; + /** + * whether to enable searching feature or not + * @default true; + */ + searchable?: boolean; + /** + * whether to select the currently focused value when the [tab] key is pressed + */ + tabSelectsValue?: boolean; + /** + * initial field value + */ + value?: Option | Options | string | string[] | number | number[] | boolean; + /** + * the option property to use for the value + * @default "value" + */ + valueKey?: string; + /** + * function which returns a custom way to render the value selected + * @default false + */ + valueRenderer?: ValueRendererHandler; + /** + * optional style to apply to the control + */ + style?: React.CSSProperties; + + /** + * optional tab index of the control + */ + tabIndex?: string | number; + + /** + * value component to render + */ + valueComponent?: ValueComponentType; + + /** + * optional style to apply to the component wrapper + */ + wrapperStyle?: React.CSSProperties; + + /** + * onClick handler for value labels: function (value, event) {} + */ + onValueClick?: OnValueClickHandler; + + /** + * pass the value to onChange as a simple value (legacy pre 1.0 mode), defaults to false + */ + simpleValue?: boolean; + } + \ No newline at end of file diff --git a/tests/baselines/reference/jsxNamespaceGlobalReexport.types b/tests/baselines/reference/jsxNamespaceGlobalReexport.types index 85fc07e3497e3..19acd72ebfed1 100644 --- a/tests/baselines/reference/jsxNamespaceGlobalReexport.types +++ b/tests/baselines/reference/jsxNamespaceGlobalReexport.types @@ -90,13 +90,13 @@ import { JSXInternal } from '..'; >JSXInternal : any export function jsx( ->jsx : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChild;}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChild | undefined; }, key?: string | undefined): VNode; } +>jsx : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChild;}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChild; }, key?: string | undefined): VNode; } type: string, >type : string props: JSXInternal.HTMLAttributes & ->props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild | undefined; } +>props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild; } >JSXInternal : any JSXInternal.SVGAttributes & @@ -110,13 +110,13 @@ export function jsx( ): VNode; export function jsx

( ->jsx : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild | undefined; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChild;}, key?: string | undefined): VNode; } +>jsx : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChild;}, key?: string | undefined): VNode; } type: ComponentType

, >type : ComponentType

props: Attributes & P & { children?: ComponentChild }, ->props : P & { children?: ComponentChild | undefined; } +>props : P & { children?: ComponentChild; } >children : ComponentChild | undefined key?: string @@ -125,13 +125,13 @@ export function jsx

( ): VNode; export function jsxs( ->jsxs : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChild[];}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChild[] | undefined; }, key?: string | undefined): VNode; } +>jsxs : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChild[];}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChild[]; }, key?: string | undefined): VNode; } type: string, >type : string props: JSXInternal.HTMLAttributes & ->props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild[] | undefined; } +>props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild[]; } >JSXInternal : any JSXInternal.SVGAttributes & @@ -145,13 +145,13 @@ export function jsxs( ): VNode; export function jsxs

( ->jsxs : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild[] | undefined; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChild[];}, key?: string | undefined): VNode; } +>jsxs : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild[]; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChild[];}, key?: string | undefined): VNode; } type: ComponentType

, >type : ComponentType

props: Attributes & P & { children?: ComponentChild[] }, ->props : P & { children?: ComponentChild[] | undefined; } +>props : P & { children?: ComponentChild[]; } >children : ComponentChild[] | undefined key?: string @@ -160,13 +160,13 @@ export function jsxs

( ): VNode; export function jsxDEV( ->jsxDEV : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChildren;}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChildren | undefined; }, key?: string | undefined): VNode; } +>jsxDEV : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChildren;}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChildren; }, key?: string | undefined): VNode; } type: string, >type : string props: JSXInternal.HTMLAttributes & ->props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChildren | undefined; } +>props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChildren; } >JSXInternal : any JSXInternal.SVGAttributes & @@ -180,13 +180,13 @@ export function jsxDEV( ): VNode; export function jsxDEV

( ->jsxDEV : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChildren | undefined; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChildren;}, key?: string | undefined): VNode; } +>jsxDEV : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChildren; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChildren;}, key?: string | undefined): VNode; } type: ComponentType

, >type : ComponentType

props: Attributes & P & { children?: ComponentChildren }, ->props : P & { children?: ComponentChildren | undefined; } +>props : P & { children?: ComponentChildren; } >children : ComponentChildren | undefined key?: string diff --git a/tests/baselines/reference/jsxNamespaceGlobalReexportMissingAliasTarget.types b/tests/baselines/reference/jsxNamespaceGlobalReexportMissingAliasTarget.types index 7cc6f7937322c..0262ca9dfafd1 100644 --- a/tests/baselines/reference/jsxNamespaceGlobalReexportMissingAliasTarget.types +++ b/tests/baselines/reference/jsxNamespaceGlobalReexportMissingAliasTarget.types @@ -90,13 +90,13 @@ import { JSXInternal } from '..'; >JSXInternal : any export function jsx( ->jsx : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChild;}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChild | undefined; }, key?: string | undefined): VNode; } +>jsx : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChild;}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChild; }, key?: string | undefined): VNode; } type: string, >type : string props: JSXInternal.HTMLAttributes & ->props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild | undefined; } +>props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild; } >JSXInternal : any JSXInternal.SVGAttributes & @@ -110,13 +110,13 @@ export function jsx( ): VNode; export function jsx

( ->jsx : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild | undefined; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChild;}, key?: string | undefined): VNode; } +>jsx : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChild;}, key?: string | undefined): VNode; } type: ComponentType

, >type : ComponentType

props: Attributes & P & { children?: ComponentChild }, ->props : P & { children?: ComponentChild | undefined; } +>props : P & { children?: ComponentChild; } >children : ComponentChild | undefined key?: string @@ -125,13 +125,13 @@ export function jsx

( ): VNode; export function jsxs( ->jsxs : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChild[];}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChild[] | undefined; }, key?: string | undefined): VNode; } +>jsxs : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChild[];}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChild[]; }, key?: string | undefined): VNode; } type: string, >type : string props: JSXInternal.HTMLAttributes & ->props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild[] | undefined; } +>props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild[]; } >JSXInternal : any JSXInternal.SVGAttributes & @@ -145,13 +145,13 @@ export function jsxs( ): VNode; export function jsxs

( ->jsxs : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild[] | undefined; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChild[];}, key?: string | undefined): VNode; } +>jsxs : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild[]; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChild[];}, key?: string | undefined): VNode; } type: ComponentType

, >type : ComponentType

props: Attributes & P & { children?: ComponentChild[] }, ->props : P & { children?: ComponentChild[] | undefined; } +>props : P & { children?: ComponentChild[]; } >children : ComponentChild[] | undefined key?: string @@ -160,13 +160,13 @@ export function jsxs

( ): VNode; export function jsxDEV( ->jsxDEV : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChildren;}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChildren | undefined; }, key?: string | undefined): VNode; } +>jsxDEV : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChildren;}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChildren; }, key?: string | undefined): VNode; } type: string, >type : string props: JSXInternal.HTMLAttributes & ->props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChildren | undefined; } +>props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChildren; } >JSXInternal : any JSXInternal.SVGAttributes & @@ -180,13 +180,13 @@ export function jsxDEV( ): VNode; export function jsxDEV

( ->jsxDEV : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChildren | undefined; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChildren;}, key?: string | undefined): VNode; } +>jsxDEV : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChildren; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChildren;}, key?: string | undefined): VNode; } type: ComponentType

, >type : ComponentType

props: Attributes & P & { children?: ComponentChildren }, ->props : P & { children?: ComponentChildren | undefined; } +>props : P & { children?: ComponentChildren; } >children : ComponentChildren | undefined key?: string diff --git a/tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.types b/tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.types index 8869f10731bb5..ee59395483c48 100644 --- a/tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.types +++ b/tests/baselines/reference/jsxNamespaceImplicitImportJSXNamespace.types @@ -90,13 +90,13 @@ import { JSXInternal } from '..'; >JSXInternal : any export function jsx( ->jsx : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChild;}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChild | undefined; }, key?: string | undefined): VNode; } +>jsx : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChild;}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChild; }, key?: string | undefined): VNode; } type: string, >type : string props: JSXInternal.HTMLAttributes & ->props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild | undefined; } +>props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild; } >JSXInternal : any JSXInternal.SVGAttributes & @@ -110,13 +110,13 @@ export function jsx( ): VNode; export function jsx

( ->jsx : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild | undefined; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChild;}, key?: string | undefined): VNode; } +>jsx : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChild;}, key?: string | undefined): VNode; } type: ComponentType

, >type : ComponentType

props: Attributes & P & { children?: ComponentChild }, ->props : P & { children?: ComponentChild | undefined; } +>props : P & { children?: ComponentChild; } >children : ComponentChild | undefined key?: string @@ -126,13 +126,13 @@ export function jsx

( export function jsxs( ->jsxs : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChild[];}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChild[] | undefined; }, key?: string | undefined): VNode; } +>jsxs : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChild[];}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChild[]; }, key?: string | undefined): VNode; } type: string, >type : string props: JSXInternal.HTMLAttributes & ->props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild[] | undefined; } +>props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild[]; } >JSXInternal : any JSXInternal.SVGAttributes & @@ -146,13 +146,13 @@ export function jsxs( ): VNode; export function jsxs

( ->jsxs : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild[] | undefined; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChild[];}, key?: string | undefined): VNode; } +>jsxs : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChild[]; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChild[];}, key?: string | undefined): VNode; } type: ComponentType

, >type : ComponentType

props: Attributes & P & { children?: ComponentChild[] }, ->props : P & { children?: ComponentChild[] | undefined; } +>props : P & { children?: ComponentChild[]; } >children : ComponentChild[] | undefined key?: string @@ -162,13 +162,13 @@ export function jsxs

( export function jsxDEV( ->jsxDEV : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChildren;}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChildren | undefined; }, key?: string | undefined): VNode; } +>jsxDEV : { (type: string, props: JSXInternal.HTMLAttributes & JSXInternal.SVGAttributes & Record & { children?: ComponentChildren;}, key?: string | undefined): VNode;

(type: ComponentType

, props: P & { children?: ComponentChildren; }, key?: string | undefined): VNode; } type: string, >type : string props: JSXInternal.HTMLAttributes & ->props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChildren | undefined; } +>props : JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChildren; } >JSXInternal : any JSXInternal.SVGAttributes & @@ -182,13 +182,13 @@ export function jsxDEV( ): VNode; export function jsxDEV

( ->jsxDEV : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChildren | undefined; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChildren;}, key?: string | undefined): VNode; } +>jsxDEV : { (type: string, props: JSXInternal.HTMLAttributes<{}> & JSXInternal.SVGAttributes<{}> & Record & { children?: ComponentChildren; }, key?: string | undefined): VNode;

(type: ComponentType

, props: Attributes & P & { children?: ComponentChildren;}, key?: string | undefined): VNode; } type: ComponentType

, >type : ComponentType

props: Attributes & P & { children?: ComponentChildren }, ->props : P & { children?: ComponentChildren | undefined; } +>props : P & { children?: ComponentChildren; } >children : ComponentChildren | undefined key?: string diff --git a/tests/baselines/reference/logicalAssignment8(target=es2015).types b/tests/baselines/reference/logicalAssignment8(target=es2015).types index ad2740ed3442d..468be31f07b9b 100644 --- a/tests/baselines/reference/logicalAssignment8(target=es2015).types +++ b/tests/baselines/reference/logicalAssignment8(target=es2015).types @@ -1,6 +1,6 @@ === tests/cases/conformance/es2021/logicalAssignment/logicalAssignment8.ts === declare const bar: { value?: number[] } | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined function foo1(results: number[] | undefined) { @@ -15,7 +15,7 @@ function foo1(results: number[] | undefined) { >results : number[] | undefined >bar?.value ?? [] : number[] >bar?.value : number[] | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined >[] : never[] >push : (...items: number[]) => number @@ -34,7 +34,7 @@ function foo2(results: number[] | undefined) { >results : number[] | undefined >bar?.value ?? [] : number[] >bar?.value : number[] | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined >[] : never[] >push : (...items: number[]) => number @@ -53,7 +53,7 @@ function foo3(results: number[] | undefined) { >results : number[] | undefined >bar?.value ?? [] : number[] >bar?.value : number[] | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined >[] : never[] >push : (...items: number[]) => number diff --git a/tests/baselines/reference/logicalAssignment8(target=es2020).types b/tests/baselines/reference/logicalAssignment8(target=es2020).types index ad2740ed3442d..468be31f07b9b 100644 --- a/tests/baselines/reference/logicalAssignment8(target=es2020).types +++ b/tests/baselines/reference/logicalAssignment8(target=es2020).types @@ -1,6 +1,6 @@ === tests/cases/conformance/es2021/logicalAssignment/logicalAssignment8.ts === declare const bar: { value?: number[] } | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined function foo1(results: number[] | undefined) { @@ -15,7 +15,7 @@ function foo1(results: number[] | undefined) { >results : number[] | undefined >bar?.value ?? [] : number[] >bar?.value : number[] | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined >[] : never[] >push : (...items: number[]) => number @@ -34,7 +34,7 @@ function foo2(results: number[] | undefined) { >results : number[] | undefined >bar?.value ?? [] : number[] >bar?.value : number[] | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined >[] : never[] >push : (...items: number[]) => number @@ -53,7 +53,7 @@ function foo3(results: number[] | undefined) { >results : number[] | undefined >bar?.value ?? [] : number[] >bar?.value : number[] | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined >[] : never[] >push : (...items: number[]) => number diff --git a/tests/baselines/reference/logicalAssignment8(target=es2021).types b/tests/baselines/reference/logicalAssignment8(target=es2021).types index ad2740ed3442d..468be31f07b9b 100644 --- a/tests/baselines/reference/logicalAssignment8(target=es2021).types +++ b/tests/baselines/reference/logicalAssignment8(target=es2021).types @@ -1,6 +1,6 @@ === tests/cases/conformance/es2021/logicalAssignment/logicalAssignment8.ts === declare const bar: { value?: number[] } | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined function foo1(results: number[] | undefined) { @@ -15,7 +15,7 @@ function foo1(results: number[] | undefined) { >results : number[] | undefined >bar?.value ?? [] : number[] >bar?.value : number[] | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined >[] : never[] >push : (...items: number[]) => number @@ -34,7 +34,7 @@ function foo2(results: number[] | undefined) { >results : number[] | undefined >bar?.value ?? [] : number[] >bar?.value : number[] | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined >[] : never[] >push : (...items: number[]) => number @@ -53,7 +53,7 @@ function foo3(results: number[] | undefined) { >results : number[] | undefined >bar?.value ?? [] : number[] >bar?.value : number[] | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined >[] : never[] >push : (...items: number[]) => number diff --git a/tests/baselines/reference/logicalAssignment8(target=esnext).types b/tests/baselines/reference/logicalAssignment8(target=esnext).types index ad2740ed3442d..468be31f07b9b 100644 --- a/tests/baselines/reference/logicalAssignment8(target=esnext).types +++ b/tests/baselines/reference/logicalAssignment8(target=esnext).types @@ -1,6 +1,6 @@ === tests/cases/conformance/es2021/logicalAssignment/logicalAssignment8.ts === declare const bar: { value?: number[] } | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined function foo1(results: number[] | undefined) { @@ -15,7 +15,7 @@ function foo1(results: number[] | undefined) { >results : number[] | undefined >bar?.value ?? [] : number[] >bar?.value : number[] | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined >[] : never[] >push : (...items: number[]) => number @@ -34,7 +34,7 @@ function foo2(results: number[] | undefined) { >results : number[] | undefined >bar?.value ?? [] : number[] >bar?.value : number[] | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined >[] : never[] >push : (...items: number[]) => number @@ -53,7 +53,7 @@ function foo3(results: number[] | undefined) { >results : number[] | undefined >bar?.value ?? [] : number[] >bar?.value : number[] | undefined ->bar : { value?: number[] | undefined; } | undefined +>bar : { value?: number[]; } | undefined >value : number[] | undefined >[] : never[] >push : (...items: number[]) => number diff --git a/tests/baselines/reference/logicalAssignment9.types b/tests/baselines/reference/logicalAssignment9.types index 76062618efb9e..f502dc93b4a03 100644 --- a/tests/baselines/reference/logicalAssignment9.types +++ b/tests/baselines/reference/logicalAssignment9.types @@ -1,19 +1,19 @@ === tests/cases/conformance/es2021/logicalAssignment/logicalAssignment9.ts === declare let x: { a?: boolean }; ->x : { a?: boolean | undefined; } +>x : { a?: boolean; } >a : boolean | undefined x.a ??= true; >x.a ??= true : boolean ->x.a : boolean | undefined ->x : { a?: boolean | undefined; } ->a : boolean | undefined +>x.a : boolean +>x : { a?: boolean; } +>a : boolean >true : true x.a &&= false; ->x.a &&= false : false | undefined ->x.a : boolean | undefined ->x : { a?: boolean | undefined; } ->a : boolean | undefined +>x.a &&= false : false +>x.a : boolean +>x : { a?: boolean; } +>a : boolean >false : false diff --git a/tests/baselines/reference/mappedTypesArraysTuples.js b/tests/baselines/reference/mappedTypesArraysTuples.js index 7bd4b03a6e54f..d1255fb2e500f 100644 --- a/tests/baselines/reference/mappedTypesArraysTuples.js +++ b/tests/baselines/reference/mappedTypesArraysTuples.js @@ -178,15 +178,15 @@ declare let y12: { }; declare function nonpartial(x: Partial): T; declare let x20: [number | undefined, string?, ...boolean[]]; -declare let y20: [number, string, ...boolean[]]; +declare let y20: [number | undefined, string, ...boolean[]]; declare let x21: (number | undefined)[]; -declare let y21: number[]; +declare let y21: (number | undefined)[]; declare let x22: { a: number | undefined; b?: string[]; }; declare let y22: { - a: number; + a: number | undefined; b: string[]; }; declare type Awaited = T extends PromiseLike ? U : T; diff --git a/tests/baselines/reference/mappedTypesArraysTuples.types b/tests/baselines/reference/mappedTypesArraysTuples.types index daa27b7958d07..b7ebbbec36765 100644 --- a/tests/baselines/reference/mappedTypesArraysTuples.types +++ b/tests/baselines/reference/mappedTypesArraysTuples.types @@ -10,7 +10,7 @@ type T00 = Boxified<[number, string?, ...boolean[]]>; >T00 : [Box, Box?, ...Box[]] type T01 = Partial<[number, string?, ...boolean[]]>; ->T01 : [(number | undefined)?, (string | undefined)?, ...(boolean | undefined)[]] +>T01 : [number?, string?, ...(boolean | undefined)[]] type T02 = Required<[number, string?, ...boolean[]]>; >T02 : [number, string, ...boolean[]] @@ -124,33 +124,33 @@ declare function nonpartial(x: Partial): T; >x : Partial declare let x20: [number | undefined, string?, ...boolean[]]; ->x20 : [number | undefined, (string | undefined)?, ...boolean[]] +>x20 : [number | undefined, string?, ...boolean[]] let y20 = nonpartial(x20); ->y20 : [number, string, ...boolean[]] ->nonpartial(x20) : [number, string, ...boolean[]] +>y20 : [number | undefined, string, ...boolean[]] +>nonpartial(x20) : [number | undefined, string, ...boolean[]] >nonpartial : (x: Partial) => T ->x20 : [number | undefined, (string | undefined)?, ...boolean[]] +>x20 : [number | undefined, string?, ...boolean[]] declare let x21: (number | undefined)[]; >x21 : (number | undefined)[] let y21 = nonpartial(x21); ->y21 : number[] ->nonpartial(x21) : number[] +>y21 : (number | undefined)[] +>nonpartial(x21) : (number | undefined)[] >nonpartial : (x: Partial) => T >x21 : (number | undefined)[] declare let x22: { a: number | undefined, b?: string[] }; ->x22 : { a: number | undefined; b?: string[] | undefined; } +>x22 : { a: number | undefined; b?: string[]; } >a : number | undefined >b : string[] | undefined let y22 = nonpartial(x22); ->y22 : { a: number; b: string[]; } ->nonpartial(x22) : { a: number; b: string[]; } +>y22 : { a: number | undefined; b: string[]; } +>nonpartial(x22) : { a: number | undefined; b: string[]; } >nonpartial : (x: Partial) => T ->x22 : { a: number | undefined; b?: string[] | undefined; } +>x22 : { a: number | undefined; b?: string[]; } type Awaited = T extends PromiseLike ? U : T; >Awaited : Awaited diff --git a/tests/baselines/reference/narrowingOfQualifiedNames.types b/tests/baselines/reference/narrowingOfQualifiedNames.types index f9ec86f075ae8..17208fb24aa1d 100644 --- a/tests/baselines/reference/narrowingOfQualifiedNames.types +++ b/tests/baselines/reference/narrowingOfQualifiedNames.types @@ -56,10 +56,10 @@ function init(properties: IProperties) { interface DeepOptional { a?: { ->a : { b?: { c?: string | undefined; } | undefined; } | undefined +>a : { b?: { c?: string;}; } | undefined b?: { ->b : { c?: string | undefined; } | undefined +>b : { c?: string; } | undefined c?: string >c : string | undefined @@ -72,32 +72,32 @@ function init2(foo: DeepOptional) { >foo : DeepOptional if (foo.a) { ->foo.a : { b?: { c?: string | undefined; } | undefined; } | undefined +>foo.a : { b?: { c?: string; }; } | undefined >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } | undefined +>a : { b?: { c?: string; }; } | undefined type A = typeof foo.a; ->A : { b?: { c?: string | undefined; } | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>A : { b?: { c?: string; }; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } +>a : { b?: { c?: string; }; } type B = typeof foo.a.b; ->B : { c?: string | undefined; } | undefined ->foo.a.b : { c?: string | undefined; } | undefined ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>B : { c?: string; } | undefined +>foo.a.b : { c?: string; } | undefined +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } ->b : { c?: string | undefined; } | undefined +>a : { b?: { c?: string; }; } +>b : { c?: string; } | undefined type C = typeof foo.a.b.c; >C : string | undefined >foo.a.b.c : string | undefined ->foo.a.b : { c?: string | undefined; } | undefined ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>foo.a.b : { c?: string; } | undefined +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } ->b : { c?: string | undefined; } | undefined +>a : { b?: { c?: string; }; } +>b : { c?: string; } | undefined >c : string | undefined for(const _ of [1]) { @@ -106,58 +106,58 @@ function init2(foo: DeepOptional) { >1 : 1 type A = typeof foo.a; ->A : { b?: { c?: string | undefined; } | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>A : { b?: { c?: string; }; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } +>a : { b?: { c?: string; }; } type B = typeof foo.a.b; ->B : { c?: string | undefined; } | undefined ->foo.a.b : { c?: string | undefined; } | undefined ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>B : { c?: string; } | undefined +>foo.a.b : { c?: string; } | undefined +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } ->b : { c?: string | undefined; } | undefined +>a : { b?: { c?: string; }; } +>b : { c?: string; } | undefined type C = typeof foo.a.b.c; >C : string | undefined >foo.a.b.c : string | undefined ->foo.a.b : { c?: string | undefined; } | undefined ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>foo.a.b : { c?: string; } | undefined +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } ->b : { c?: string | undefined; } | undefined +>a : { b?: { c?: string; }; } +>b : { c?: string; } | undefined >c : string | undefined if (foo.a.b) { ->foo.a.b : { c?: string | undefined; } | undefined ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>foo.a.b : { c?: string; } | undefined +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } ->b : { c?: string | undefined; } | undefined +>a : { b?: { c?: string; }; } +>b : { c?: string; } | undefined type A = typeof foo.a; ->A : { b?: { c?: string | undefined; } | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>A : { b?: { c?: string; }; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } +>a : { b?: { c?: string; }; } type B = typeof foo.a.b; ->B : { c?: string | undefined; } ->foo.a.b : { c?: string | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>B : { c?: string; } +>foo.a.b : { c?: string; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } ->b : { c?: string | undefined; } +>a : { b?: { c?: string; }; } +>b : { c?: string; } type C = typeof foo.a.b.c; >C : string | undefined >foo.a.b.c : string | undefined ->foo.a.b : { c?: string | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>foo.a.b : { c?: string; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } ->b : { c?: string | undefined; } +>a : { b?: { c?: string; }; } +>b : { c?: string; } >c : string | undefined for(const _ of [1]) { @@ -166,60 +166,60 @@ function init2(foo: DeepOptional) { >1 : 1 type A = typeof foo.a; ->A : { b?: { c?: string | undefined; } | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>A : { b?: { c?: string; }; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } +>a : { b?: { c?: string; }; } type B = typeof foo.a.b; ->B : { c?: string | undefined; } ->foo.a.b : { c?: string | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>B : { c?: string; } +>foo.a.b : { c?: string; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } ->b : { c?: string | undefined; } +>a : { b?: { c?: string; }; } +>b : { c?: string; } type C = typeof foo.a.b.c; >C : string | undefined >foo.a.b.c : string | undefined ->foo.a.b : { c?: string | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>foo.a.b : { c?: string; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } ->b : { c?: string | undefined; } +>a : { b?: { c?: string; }; } +>b : { c?: string; } >c : string | undefined if (foo.a.b.c) { >foo.a.b.c : string | undefined ->foo.a.b : { c?: string | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>foo.a.b : { c?: string; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } ->b : { c?: string | undefined; } +>a : { b?: { c?: string; }; } +>b : { c?: string; } >c : string | undefined type A = typeof foo.a; ->A : { b?: { c?: string | undefined; } | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>A : { b?: { c?: string; }; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } +>a : { b?: { c?: string; }; } type B = typeof foo.a.b; ->B : { c?: string | undefined; } ->foo.a.b : { c?: string | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>B : { c?: string; } +>foo.a.b : { c?: string; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } ->b : { c?: string | undefined; } +>a : { b?: { c?: string; }; } +>b : { c?: string; } type C = typeof foo.a.b.c; >C : string >foo.a.b.c : string ->foo.a.b : { c?: string | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>foo.a.b : { c?: string; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } ->b : { c?: string | undefined; } +>a : { b?: { c?: string; }; } +>b : { c?: string; } >c : string for(const _ of [1]) { @@ -228,27 +228,27 @@ function init2(foo: DeepOptional) { >1 : 1 type A = typeof foo.a; ->A : { b?: { c?: string | undefined; } | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>A : { b?: { c?: string; }; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } +>a : { b?: { c?: string; }; } type B = typeof foo.a.b; ->B : { c?: string | undefined; } ->foo.a.b : { c?: string | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>B : { c?: string; } +>foo.a.b : { c?: string; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } ->b : { c?: string | undefined; } +>a : { b?: { c?: string; }; } +>b : { c?: string; } type C = typeof foo.a.b.c; >C : string >foo.a.b.c : string ->foo.a.b : { c?: string | undefined; } ->foo.a : { b?: { c?: string | undefined; } | undefined; } +>foo.a.b : { c?: string; } +>foo.a : { b?: { c?: string; }; } >foo : DeepOptional ->a : { b?: { c?: string | undefined; } | undefined; } ->b : { c?: string | undefined; } +>a : { b?: { c?: string; }; } +>b : { c?: string; } >c : string } } diff --git a/tests/baselines/reference/noUncheckedIndexedAccessDestructuring.types b/tests/baselines/reference/noUncheckedIndexedAccessDestructuring.types index 8e923b5c82a24..228e7c80e4795 100644 --- a/tests/baselines/reference/noUncheckedIndexedAccessDestructuring.types +++ b/tests/baselines/reference/noUncheckedIndexedAccessDestructuring.types @@ -158,7 +158,7 @@ declare let target_string_arr: string[]; [,,, ...target_string_arr] = strArray; // Should OK >[,,, ...target_string_arr] = strArray : string[] ->[,,, ...target_string_arr] : [undefined, undefined, undefined, ...string[]] +>[,,, ...target_string_arr] : [never?, never?, never?, ...string[]] > : undefined > : undefined > : undefined diff --git a/tests/baselines/reference/normalizedIntersectionTooComplex.types b/tests/baselines/reference/normalizedIntersectionTooComplex.types index e7a49a5058317..369b087cf8d24 100644 --- a/tests/baselines/reference/normalizedIntersectionTooComplex.types +++ b/tests/baselines/reference/normalizedIntersectionTooComplex.types @@ -20,112 +20,112 @@ type CtorOf = (arg: UnionToIntersection) => T; interface Big { "0": { common?: string; "0"?: number, ref?: Obj | Func; } ->"0" : { common?: string | undefined; "0"?: number | undefined; ref?: Obj | Func | undefined; } +>"0" : { common?: string; "0"?: number; ref?: Obj | Func; } >common : string | undefined >"0" : number | undefined ->ref : Obj<{ common?: string | undefined; "0"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "0"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "0"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "0"?: number; ref?: Obj | Func; }> | undefined "1": { common?: string; "1"?: number, ref?: Obj | Func; } ->"1" : { common?: string | undefined; "1"?: number | undefined; ref?: Obj | Func | undefined; } +>"1" : { common?: string; "1"?: number; ref?: Obj | Func; } >common : string | undefined >"1" : number | undefined ->ref : Obj<{ common?: string | undefined; "1"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "1"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "1"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "1"?: number; ref?: Obj | Func; }> | undefined "2": { common?: string; "2"?: number, ref?: Obj | Func; } ->"2" : { common?: string | undefined; "2"?: number | undefined; ref?: Obj | Func | undefined; } +>"2" : { common?: string; "2"?: number; ref?: Obj | Func; } >common : string | undefined >"2" : number | undefined ->ref : Obj<{ common?: string | undefined; "2"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "2"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "2"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "2"?: number; ref?: Obj | Func; }> | undefined "3": { common?: string; "3"?: number, ref?: Obj | Func; } ->"3" : { common?: string | undefined; "3"?: number | undefined; ref?: Obj | Func | undefined; } +>"3" : { common?: string; "3"?: number; ref?: Obj | Func; } >common : string | undefined >"3" : number | undefined ->ref : Obj<{ common?: string | undefined; "3"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "3"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "3"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "3"?: number; ref?: Obj | Func; }> | undefined "4": { common?: string; "4"?: number, ref?: Obj | Func; } ->"4" : { common?: string | undefined; "4"?: number | undefined; ref?: Obj | Func | undefined; } +>"4" : { common?: string; "4"?: number; ref?: Obj | Func; } >common : string | undefined >"4" : number | undefined ->ref : Obj<{ common?: string | undefined; "4"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "4"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "4"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "4"?: number; ref?: Obj | Func; }> | undefined "5": { common?: string; "5"?: number, ref?: Obj | Func; } ->"5" : { common?: string | undefined; "5"?: number | undefined; ref?: Obj | Func | undefined; } +>"5" : { common?: string; "5"?: number; ref?: Obj | Func; } >common : string | undefined >"5" : number | undefined ->ref : Obj<{ common?: string | undefined; "5"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "5"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "5"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "5"?: number; ref?: Obj | Func; }> | undefined "6": { common?: string; "6"?: number, ref?: Obj | Func; } ->"6" : { common?: string | undefined; "6"?: number | undefined; ref?: Obj | Func | undefined; } +>"6" : { common?: string; "6"?: number; ref?: Obj | Func; } >common : string | undefined >"6" : number | undefined ->ref : Obj<{ common?: string | undefined; "6"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "6"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "6"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "6"?: number; ref?: Obj | Func; }> | undefined "7": { common?: string; "7"?: number, ref?: Obj | Func; } ->"7" : { common?: string | undefined; "7"?: number | undefined; ref?: Obj | Func | undefined; } +>"7" : { common?: string; "7"?: number; ref?: Obj | Func; } >common : string | undefined >"7" : number | undefined ->ref : Obj<{ common?: string | undefined; "7"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "7"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "7"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "7"?: number; ref?: Obj | Func; }> | undefined "8": { common?: string; "8"?: number, ref?: Obj | Func; } ->"8" : { common?: string | undefined; "8"?: number | undefined; ref?: Obj | Func | undefined; } +>"8" : { common?: string; "8"?: number; ref?: Obj | Func; } >common : string | undefined >"8" : number | undefined ->ref : Obj<{ common?: string | undefined; "8"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "8"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "8"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "8"?: number; ref?: Obj | Func; }> | undefined "9": { common?: string; "9"?: number, ref?: Obj | Func; } ->"9" : { common?: string | undefined; "9"?: number | undefined; ref?: Obj | Func | undefined; } +>"9" : { common?: string; "9"?: number; ref?: Obj | Func; } >common : string | undefined >"9" : number | undefined ->ref : Obj<{ common?: string | undefined; "9"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "9"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "9"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "9"?: number; ref?: Obj | Func; }> | undefined "10": { common?: string; "10"?: number, ref?: Obj | Func; } ->"10" : { common?: string | undefined; "10"?: number | undefined; ref?: Obj | Func | undefined; } +>"10" : { common?: string; "10"?: number; ref?: Obj | Func; } >common : string | undefined >"10" : number | undefined ->ref : Obj<{ common?: string | undefined; "10"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "10"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "10"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "10"?: number; ref?: Obj | Func; }> | undefined "11": { common?: string; "11"?: number, ref?: Obj | Func; } ->"11" : { common?: string | undefined; "11"?: number | undefined; ref?: Obj | Func | undefined; } +>"11" : { common?: string; "11"?: number; ref?: Obj | Func; } >common : string | undefined >"11" : number | undefined ->ref : Obj<{ common?: string | undefined; "11"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "11"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "11"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "11"?: number; ref?: Obj | Func; }> | undefined "12": { common?: string; "12"?: number, ref?: Obj | Func; } ->"12" : { common?: string | undefined; "12"?: number | undefined; ref?: Obj | Func | undefined; } +>"12" : { common?: string; "12"?: number; ref?: Obj | Func; } >common : string | undefined >"12" : number | undefined ->ref : Obj<{ common?: string | undefined; "12"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "12"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "12"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "12"?: number; ref?: Obj | Func; }> | undefined "13": { common?: string; "13"?: number, ref?: Obj | Func; } ->"13" : { common?: string | undefined; "13"?: number | undefined; ref?: Obj | Func | undefined; } +>"13" : { common?: string; "13"?: number; ref?: Obj | Func; } >common : string | undefined >"13" : number | undefined ->ref : Obj<{ common?: string | undefined; "13"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "13"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "13"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "13"?: number; ref?: Obj | Func; }> | undefined "14": { common?: string; "14"?: number, ref?: Obj | Func; } ->"14" : { common?: string | undefined; "14"?: number | undefined; ref?: Obj | Func | undefined; } +>"14" : { common?: string; "14"?: number; ref?: Obj | Func; } >common : string | undefined >"14" : number | undefined ->ref : Obj<{ common?: string | undefined; "14"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "14"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "14"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "14"?: number; ref?: Obj | Func; }> | undefined "15": { common?: string; "15"?: number, ref?: Obj | Func; } ->"15" : { common?: string | undefined; "15"?: number | undefined; ref?: Obj | Func | undefined; } +>"15" : { common?: string; "15"?: number; ref?: Obj | Func; } >common : string | undefined >"15" : number | undefined ->ref : Obj<{ common?: string | undefined; "15"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "15"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "15"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "15"?: number; ref?: Obj | Func; }> | undefined "16": { common?: string; "16"?: number, ref?: Obj | Func; } ->"16" : { common?: string | undefined; "16"?: number | undefined; ref?: Obj | Func | undefined; } +>"16" : { common?: string; "16"?: number; ref?: Obj | Func; } >common : string | undefined >"16" : number | undefined ->ref : Obj<{ common?: string | undefined; "16"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "16"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "16"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "16"?: number; ref?: Obj | Func; }> | undefined "17": { common?: string; "17"?: number, ref?: Obj | Func; } ->"17" : { common?: string | undefined; "17"?: number | undefined; ref?: Obj | Func | undefined; } +>"17" : { common?: string; "17"?: number; ref?: Obj | Func; } >common : string | undefined >"17" : number | undefined ->ref : Obj<{ common?: string | undefined; "17"?: number | undefined; ref?: Obj | Func | undefined; }> | Func<{ common?: string | undefined; "17"?: number | undefined; ref?: Obj | Func | undefined; }> | undefined +>ref : Obj<{ common?: string; "17"?: number; ref?: Obj | Func; }> | Func<{ common?: string; "17"?: number; ref?: Obj | Func; }> | undefined } declare function getCtor(comp: T): CtorOf >getCtor : (comp: T) => CtorOf @@ -135,15 +135,15 @@ declare var all: keyof Big; >all : keyof Big const ctor = getCtor(all); ->ctor : CtorOf<{ common?: string | undefined; "0"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "1"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "2"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "3"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "4"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "5"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "6"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "7"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "8"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "9"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "10"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "11"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "12"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "13"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "14"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "15"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "16"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "17"?: number | undefined; ref?: Obj | Func | undefined; }> ->getCtor(all) : CtorOf<{ common?: string | undefined; "0"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "1"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "2"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "3"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "4"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "5"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "6"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "7"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "8"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "9"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "10"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "11"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "12"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "13"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "14"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "15"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "16"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "17"?: number | undefined; ref?: Obj | Func | undefined; }> +>ctor : CtorOf<{ common?: string; "0"?: number; ref?: Obj | Func; } | { common?: string; "1"?: number; ref?: Obj | Func; } | { common?: string; "2"?: number; ref?: Obj | Func; } | { common?: string; "3"?: number; ref?: Obj | Func; } | { common?: string; "4"?: number; ref?: Obj | Func; } | { common?: string; "5"?: number; ref?: Obj | Func; } | { common?: string; "6"?: number; ref?: Obj | Func; } | { common?: string; "7"?: number; ref?: Obj | Func; } | { common?: string; "8"?: number; ref?: Obj | Func; } | { common?: string; "9"?: number; ref?: Obj | Func; } | { common?: string; "10"?: number; ref?: Obj | Func; } | { common?: string; "11"?: number; ref?: Obj | Func; } | { common?: string; "12"?: number; ref?: Obj | Func; } | { common?: string; "13"?: number; ref?: Obj | Func; } | { common?: string; "14"?: number; ref?: Obj | Func; } | { common?: string; "15"?: number; ref?: Obj | Func; } | { common?: string; "16"?: number; ref?: Obj | Func; } | { common?: string; "17"?: number; ref?: Obj | Func; }> +>getCtor(all) : CtorOf<{ common?: string; "0"?: number; ref?: Obj | Func; } | { common?: string; "1"?: number; ref?: Obj | Func; } | { common?: string; "2"?: number; ref?: Obj | Func; } | { common?: string; "3"?: number; ref?: Obj | Func; } | { common?: string; "4"?: number; ref?: Obj | Func; } | { common?: string; "5"?: number; ref?: Obj | Func; } | { common?: string; "6"?: number; ref?: Obj | Func; } | { common?: string; "7"?: number; ref?: Obj | Func; } | { common?: string; "8"?: number; ref?: Obj | Func; } | { common?: string; "9"?: number; ref?: Obj | Func; } | { common?: string; "10"?: number; ref?: Obj | Func; } | { common?: string; "11"?: number; ref?: Obj | Func; } | { common?: string; "12"?: number; ref?: Obj | Func; } | { common?: string; "13"?: number; ref?: Obj | Func; } | { common?: string; "14"?: number; ref?: Obj | Func; } | { common?: string; "15"?: number; ref?: Obj | Func; } | { common?: string; "16"?: number; ref?: Obj | Func; } | { common?: string; "17"?: number; ref?: Obj | Func; }> >getCtor : (comp: T) => CtorOf >all : keyof Big const comp = ctor({ common: "ok", ref: x => console.log(x) }); ->comp : { common?: string | undefined; "0"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "1"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "2"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "3"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "4"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "5"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "6"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "7"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "8"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "9"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "10"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "11"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "12"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "13"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "14"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "15"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "16"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "17"?: number | undefined; ref?: Obj | Func | undefined; } ->ctor({ common: "ok", ref: x => console.log(x) }) : { common?: string | undefined; "0"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "1"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "2"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "3"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "4"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "5"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "6"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "7"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "8"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "9"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "10"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "11"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "12"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "13"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "14"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "15"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "16"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "17"?: number | undefined; ref?: Obj | Func | undefined; } ->ctor : CtorOf<{ common?: string | undefined; "0"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "1"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "2"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "3"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "4"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "5"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "6"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "7"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "8"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "9"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "10"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "11"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "12"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "13"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "14"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "15"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "16"?: number | undefined; ref?: Obj | Func | undefined; } | { common?: string | undefined; "17"?: number | undefined; ref?: Obj | Func | undefined; }> +>comp : { common?: string; "0"?: number; ref?: Obj | Func; } | { common?: string; "1"?: number; ref?: Obj | Func; } | { common?: string; "2"?: number; ref?: Obj | Func; } | { common?: string; "3"?: number; ref?: Obj | Func; } | { common?: string; "4"?: number; ref?: Obj | Func; } | { common?: string; "5"?: number; ref?: Obj | Func; } | { common?: string; "6"?: number; ref?: Obj | Func; } | { common?: string; "7"?: number; ref?: Obj | Func; } | { common?: string; "8"?: number; ref?: Obj | Func; } | { common?: string; "9"?: number; ref?: Obj | Func; } | { common?: string; "10"?: number; ref?: Obj | Func; } | { common?: string; "11"?: number; ref?: Obj | Func; } | { common?: string; "12"?: number; ref?: Obj | Func; } | { common?: string; "13"?: number; ref?: Obj | Func; } | { common?: string; "14"?: number; ref?: Obj | Func; } | { common?: string; "15"?: number; ref?: Obj | Func; } | { common?: string; "16"?: number; ref?: Obj | Func; } | { common?: string; "17"?: number; ref?: Obj | Func; } +>ctor({ common: "ok", ref: x => console.log(x) }) : { common?: string; "0"?: number; ref?: Obj | Func; } | { common?: string; "1"?: number; ref?: Obj | Func; } | { common?: string; "2"?: number; ref?: Obj | Func; } | { common?: string; "3"?: number; ref?: Obj | Func; } | { common?: string; "4"?: number; ref?: Obj | Func; } | { common?: string; "5"?: number; ref?: Obj | Func; } | { common?: string; "6"?: number; ref?: Obj | Func; } | { common?: string; "7"?: number; ref?: Obj | Func; } | { common?: string; "8"?: number; ref?: Obj | Func; } | { common?: string; "9"?: number; ref?: Obj | Func; } | { common?: string; "10"?: number; ref?: Obj | Func; } | { common?: string; "11"?: number; ref?: Obj | Func; } | { common?: string; "12"?: number; ref?: Obj | Func; } | { common?: string; "13"?: number; ref?: Obj | Func; } | { common?: string; "14"?: number; ref?: Obj | Func; } | { common?: string; "15"?: number; ref?: Obj | Func; } | { common?: string; "16"?: number; ref?: Obj | Func; } | { common?: string; "17"?: number; ref?: Obj | Func; } +>ctor : CtorOf<{ common?: string; "0"?: number; ref?: Obj | Func; } | { common?: string; "1"?: number; ref?: Obj | Func; } | { common?: string; "2"?: number; ref?: Obj | Func; } | { common?: string; "3"?: number; ref?: Obj | Func; } | { common?: string; "4"?: number; ref?: Obj | Func; } | { common?: string; "5"?: number; ref?: Obj | Func; } | { common?: string; "6"?: number; ref?: Obj | Func; } | { common?: string; "7"?: number; ref?: Obj | Func; } | { common?: string; "8"?: number; ref?: Obj | Func; } | { common?: string; "9"?: number; ref?: Obj | Func; } | { common?: string; "10"?: number; ref?: Obj | Func; } | { common?: string; "11"?: number; ref?: Obj | Func; } | { common?: string; "12"?: number; ref?: Obj | Func; } | { common?: string; "13"?: number; ref?: Obj | Func; } | { common?: string; "14"?: number; ref?: Obj | Func; } | { common?: string; "15"?: number; ref?: Obj | Func; } | { common?: string; "16"?: number; ref?: Obj | Func; } | { common?: string; "17"?: number; ref?: Obj | Func; }> >{ common: "ok", ref: x => console.log(x) } : { common: string; ref: (x: any) => void; } >common : string >"ok" : "ok" diff --git a/tests/baselines/reference/numericEnumMappedType.types b/tests/baselines/reference/numericEnumMappedType.types index bffec2ed8ca18..284923f54dc9e 100644 --- a/tests/baselines/reference/numericEnumMappedType.types +++ b/tests/baselines/reference/numericEnumMappedType.types @@ -41,14 +41,14 @@ const e2: E2 = E2.ONE; b1[1] = "a"; >b1[1] = "a" : "a" ->b1[1] : string | undefined +>b1[1] : string >b1 : Bins1 >1 : 1 >"a" : "a" b1[e1] = "b"; >b1[e1] = "b" : "b" ->b1[e1] : string | undefined +>b1[e1] : string >b1 : Bins1 >e1 : E1.ONE >"b" : "b" diff --git a/tests/baselines/reference/objectLiteralNormalization.errors.txt b/tests/baselines/reference/objectLiteralNormalization.errors.txt index bd14787178ba9..c7fa353f2b37b 100644 --- a/tests/baselines/reference/objectLiteralNormalization.errors.txt +++ b/tests/baselines/reference/objectLiteralNormalization.errors.txt @@ -1,13 +1,13 @@ -tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(7,14): error TS2322: Type 'number' is not assignable to type 'string | undefined'. -tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(8,1): error TS2322: Type '{ b: string; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'. +tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(7,14): error TS2322: Type 'number' is not assignable to type 'string'. +tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(8,1): error TS2322: Type '{ b: string; }' is not assignable to type '{ a: number; b?: never; c?: never; } | { a: number; b: string; c?: never; } | { a: number; b: string; c: boolean; }'. Type '{ b: string; }' is missing the following properties from type '{ a: number; b: string; c: boolean; }': a, c -tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(9,1): error TS2322: Type '{ c: true; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'. +tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(9,1): error TS2322: Type '{ c: true; }' is not assignable to type '{ a: number; b?: never; c?: never; } | { a: number; b: string; c?: never; } | { a: number; b: string; c: boolean; }'. Type '{ c: true; }' is missing the following properties from type '{ a: number; b: string; c: boolean; }': a, b -tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(17,1): error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'. - Type '{ a: string; b: number; }' is not assignable to type '{ a?: undefined; b?: undefined; }'. +tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(17,1): error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: never; } | { a?: never; b?: never; }'. + Type '{ a: string; b: number; }' is not assignable to type '{ a?: never; b?: never; }'. Types of property 'a' are incompatible. - Type 'string' is not assignable to type 'undefined'. -tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(18,1): error TS2322: Type '{ a: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'. + Type 'string' is not assignable to type 'never'. +tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(18,1): error TS2322: Type '{ a: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: never; } | { a?: never; b?: never; }'. Property 'b' is missing in type '{ a: number; }' but required in type '{ a: number; b: number; }'. tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(48,20): error TS2322: Type '2' is not assignable to type '1'. tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(49,14): error TS2322: Type '2' is not assignable to type '1'. @@ -22,15 +22,15 @@ tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts a1 = { a: 1 }; a1 = { a: 0, b: 0 }; // Error ~ -!!! error TS2322: Type 'number' is not assignable to type 'string | undefined'. -!!! related TS6500 tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts:2:47: The expected type comes from property 'b' which is declared here on type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }' +!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! related TS6500 tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts:2:47: The expected type comes from property 'b' which is declared here on type '{ a: number; b?: never; c?: never; } | { a: number; b: string; c?: never; } | { a: number; b: string; c: boolean; }' a1 = { b: "y" }; // Error ~~ -!!! error TS2322: Type '{ b: string; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'. +!!! error TS2322: Type '{ b: string; }' is not assignable to type '{ a: number; b?: never; c?: never; } | { a: number; b: string; c?: never; } | { a: number; b: string; c: boolean; }'. !!! error TS2322: Type '{ b: string; }' is missing the following properties from type '{ a: number; b: string; c: boolean; }': a, c a1 = { c: true }; // Error ~~ -!!! error TS2322: Type '{ c: true; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'. +!!! error TS2322: Type '{ c: true; }' is not assignable to type '{ a: number; b?: never; c?: never; } | { a: number; b: string; c?: never; } | { a: number; b: string; c: boolean; }'. !!! error TS2322: Type '{ c: true; }' is missing the following properties from type '{ a: number; b: string; c: boolean; }': a, b let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0]; @@ -41,13 +41,13 @@ tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts a2 = {}; a2 = { a: "def", b: 20 }; // Error ~~ -!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'. -!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a?: undefined; b?: undefined; }'. +!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: never; } | { a?: never; b?: never; }'. +!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a?: never; b?: never; }'. !!! error TS2322: Types of property 'a' are incompatible. -!!! error TS2322: Type 'string' is not assignable to type 'undefined'. +!!! error TS2322: Type 'string' is not assignable to type 'never'. a2 = { a: 1 }; // Error ~~ -!!! error TS2322: Type '{ a: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'. +!!! error TS2322: Type '{ a: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: never; } | { a?: never; b?: never; }'. !!! error TS2322: Property 'b' is missing in type '{ a: number; }' but required in type '{ a: number; b: number; }'. !!! related TS2728 tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts:11:19: 'b' is declared here. diff --git a/tests/baselines/reference/objectLiteralNormalization.js b/tests/baselines/reference/objectLiteralNormalization.js index aa2fa9c7ec2e0..3f220403e89a4 100644 --- a/tests/baselines/reference/objectLiteralNormalization.js +++ b/tests/baselines/reference/objectLiteralNormalization.js @@ -104,12 +104,12 @@ var e4 = f({ a: 2 }, data); //// [objectLiteralNormalization.d.ts] declare let a1: { a: number; - b?: undefined; - c?: undefined; + b?: never; + c?: never; } | { a: number; b: string; - c?: undefined; + c?: never; } | { a: number; b: string; @@ -120,10 +120,10 @@ declare let a2: { b: number; } | { a: string; - b?: undefined; + b?: never; } | { - a?: undefined; - b?: undefined; + a?: never; + b?: never; }; declare let b1: { a: string; @@ -156,25 +156,25 @@ declare let opts: { baz?: boolean; }; declare let c1: { - foo?: string | undefined; - bar?: string | undefined; - baz?: boolean | undefined; + foo?: string; + bar?: string; + baz?: boolean; }; declare let c2: { - foo?: string | undefined; - bar?: string | undefined; - baz?: boolean | undefined; + foo?: string; + bar?: string; + baz?: boolean; }; declare let c3: { a: number; b: number; } | { - a?: undefined; - b?: undefined; + a?: never; + b?: never; }; declare let c4: { - a?: undefined; - b?: undefined; + a?: never; + b?: never; } | { a: number; b: number; @@ -184,21 +184,21 @@ declare let d1: { pos: { x: number; y: number; - a?: undefined; - b?: undefined; + a?: never; + b?: never; }; } | { kind: string; pos: { a: string; - x?: undefined; - y?: undefined; - b?: undefined; + x?: never; + y?: never; + b?: never; } | { b: number; - x?: undefined; - y?: undefined; - a?: undefined; + x?: never; + y?: never; + a?: never; }; }; declare function f(...items: T[]): T; @@ -212,17 +212,17 @@ declare let e1: { b: number; } | { a: string; - b?: undefined; + b?: never; } | { - a?: undefined; - b?: undefined; + a?: never; + b?: never; }; declare let e2: { - a?: undefined; - b?: undefined; + a?: never; + b?: never; } | { a: string; - b?: undefined; + b?: never; } | { a: number; b: number; diff --git a/tests/baselines/reference/objectLiteralNormalization.types b/tests/baselines/reference/objectLiteralNormalization.types index 28cf4bed6f792..9f4710df64f0b 100644 --- a/tests/baselines/reference/objectLiteralNormalization.types +++ b/tests/baselines/reference/objectLiteralNormalization.types @@ -1,7 +1,7 @@ === tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts === // Object literals in unions are normalized upon widening let a1 = [{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0]; ->a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; } +>a1 : { a: number; b?: never; c?: never; } | { a: number; b: string; c?: never; } | { a: number; b: string; c: boolean; } >[{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0] : { a: number; } | { a: number; b: string; } | { a: number; b: string; c: boolean; } >[{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }] : ({ a: number; } | { a: number; b: string; } | { a: number; b: string; c: boolean; })[] >{ a: 0 } : { a: number; } @@ -23,29 +23,29 @@ let a1 = [{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0]; a1.a; // number >a1.a : number ->a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; } +>a1 : { a: number; b?: never; c?: never; } | { a: number; b: string; c?: never; } | { a: number; b: string; c: boolean; } >a : number a1.b; // string | undefined >a1.b : string | undefined ->a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; } +>a1 : { a: number; b?: never; c?: never; } | { a: number; b: string; c?: never; } | { a: number; b: string; c: boolean; } >b : string | undefined a1.c; // boolean | undefined >a1.c : boolean | undefined ->a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; } +>a1 : { a: number; b?: never; c?: never; } | { a: number; b: string; c?: never; } | { a: number; b: string; c: boolean; } >c : boolean | undefined a1 = { a: 1 }; >a1 = { a: 1 } : { a: number; } ->a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; } +>a1 : { a: number; b?: never; c?: never; } | { a: number; b: string; c?: never; } | { a: number; b: string; c: boolean; } >{ a: 1 } : { a: number; } >a : number >1 : 1 a1 = { a: 0, b: 0 }; // Error >a1 = { a: 0, b: 0 } : { a: number; b: number; } ->a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; } +>a1 : { a: number; b?: never; c?: never; } | { a: number; b: string; c?: never; } | { a: number; b: string; c: boolean; } >{ a: 0, b: 0 } : { a: number; b: number; } >a : number >0 : 0 @@ -54,20 +54,20 @@ a1 = { a: 0, b: 0 }; // Error a1 = { b: "y" }; // Error >a1 = { b: "y" } : { b: string; } ->a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; } +>a1 : { a: number; b?: never; c?: never; } | { a: number; b: string; c?: never; } | { a: number; b: string; c: boolean; } >{ b: "y" } : { b: string; } >b : string >"y" : "y" a1 = { c: true }; // Error >a1 = { c: true } : { c: true; } ->a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; } +>a1 : { a: number; b?: never; c?: never; } | { a: number; b: string; c?: never; } | { a: number; b: string; c: boolean; } >{ c: true } : { c: true; } >c : true >true : true let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0]; ->a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; } +>a2 : { a: number; b: number; } | { a: string; b?: never; } | { a?: never; b?: never; } >[{ a: 1, b: 2 }, { a: "abc" }, {}][0] : { a: number; b: number; } | { a: string; } | {} >[{ a: 1, b: 2 }, { a: "abc" }, {}] : ({ a: number; b: number; } | { a: string; } | {})[] >{ a: 1, b: 2 } : { a: number; b: number; } @@ -83,17 +83,17 @@ let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0]; a2.a; // string | number | undefined >a2.a : string | number | undefined ->a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; } +>a2 : { a: number; b: number; } | { a: string; b?: never; } | { a?: never; b?: never; } >a : string | number | undefined a2.b; // number | undefined >a2.b : number | undefined ->a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; } +>a2 : { a: number; b: number; } | { a: string; b?: never; } | { a?: never; b?: never; } >b : number | undefined a2 = { a: 10, b: 20 }; >a2 = { a: 10, b: 20 } : { a: number; b: number; } ->a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; } +>a2 : { a: number; b: number; } | { a: string; b?: never; } | { a?: never; b?: never; } >{ a: 10, b: 20 } : { a: number; b: number; } >a : number >10 : 10 @@ -102,19 +102,19 @@ a2 = { a: 10, b: 20 }; a2 = { a: "def" }; >a2 = { a: "def" } : { a: string; } ->a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; } +>a2 : { a: number; b: number; } | { a: string; b?: never; } | { a?: never; b?: never; } >{ a: "def" } : { a: string; } >a : string >"def" : "def" a2 = {}; >a2 = {} : {} ->a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; } +>a2 : { a: number; b: number; } | { a: string; b?: never; } | { a?: never; b?: never; } >{} : {} a2 = { a: "def", b: 20 }; // Error >a2 = { a: "def", b: 20 } : { a: string; b: number; } ->a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; } +>a2 : { a: number; b: number; } | { a: string; b?: never; } | { a?: never; b?: never; } >{ a: "def", b: 20 } : { a: string; b: number; } >a : string >"def" : "def" @@ -123,7 +123,7 @@ a2 = { a: "def", b: 20 }; // Error a2 = { a: 1 }; // Error >a2 = { a: 1 } : { a: number; } ->a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; } +>a2 : { a: number; b: number; } | { a: string; b?: never; } | { a?: never; b?: never; } >{ a: 1 } : { a: number; } >a : number >1 : 1 @@ -151,29 +151,29 @@ let b3 = { ...b2 }; // Before widening {} acts like { [x: string]: undefined }, which is a // subtype of types with all optional properties declare let opts: { foo?: string, bar?: string, baz?: boolean }; ->opts : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; } +>opts : { foo?: string; bar?: string; baz?: boolean; } >foo : string | undefined >bar : string | undefined >baz : boolean | undefined let c1 = !true ? {} : opts; ->c1 : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; } ->!true ? {} : opts : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; } +>c1 : { foo?: string; bar?: string; baz?: boolean; } +>!true ? {} : opts : { foo?: string; bar?: string; baz?: boolean; } >!true : false >true : true >{} : {} ->opts : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; } +>opts : { foo?: string; bar?: string; baz?: boolean; } let c2 = !true ? opts : {}; ->c2 : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; } ->!true ? opts : {} : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; } +>c2 : { foo?: string; bar?: string; baz?: boolean; } +>!true ? opts : {} : { foo?: string; bar?: string; baz?: boolean; } >!true : false >true : true ->opts : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; } +>opts : { foo?: string; bar?: string; baz?: boolean; } >{} : {} let c3 = !true ? { a: 0, b: 0 } : {}; ->c3 : { a: number; b: number; } | { a?: undefined; b?: undefined; } +>c3 : { a: number; b: number; } | { a?: never; b?: never; } >!true ? { a: 0, b: 0 } : {} : { a: number; b: number; } | {} >!true : false >true : true @@ -185,7 +185,7 @@ let c3 = !true ? { a: 0, b: 0 } : {}; >{} : {} let c4 = !true ? {} : { a: 0, b: 0 }; ->c4 : { a?: undefined; b?: undefined; } | { a: number; b: number; } +>c4 : { a?: never; b?: never; } | { a: number; b: number; } >!true ? {} : { a: 0, b: 0 } : {} | { a: number; b: number; } >!true : false >true : true @@ -198,7 +198,7 @@ let c4 = !true ? {} : { a: 0, b: 0 }; // Normalization applies to nested properties let d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0]; ->d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; } +>d1 : { kind: string; pos: { x: number; y: number; a?: never; b?: never; }; } | { kind: string; pos: { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; }; } >[{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0] : { kind: string; pos: { x: number; y: number; }; } | { kind: string; pos: { a: string; } | { b: number; }; } >[{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }] : ({ kind: string; pos: { x: number; y: number; }; } | { kind: string; pos: { a: string; } | { b: number; }; })[] >{ kind: 'a', pos: { x: 0, y: 0 } } : { kind: string; pos: { x: number; y: number; }; } @@ -227,40 +227,40 @@ let d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" d1.kind; >d1.kind : string ->d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; } +>d1 : { kind: string; pos: { x: number; y: number; a?: never; b?: never; }; } | { kind: string; pos: { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; }; } >kind : string d1.pos; ->d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; } ->d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; } ->pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; } +>d1.pos : { x: number; y: number; a?: never; b?: never; } | { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; } +>d1 : { kind: string; pos: { x: number; y: number; a?: never; b?: never; }; } | { kind: string; pos: { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; }; } +>pos : { x: number; y: number; a?: never; b?: never; } | { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; } d1.pos.x; >d1.pos.x : number | undefined ->d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; } ->d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; } ->pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; } +>d1.pos : { x: number; y: number; a?: never; b?: never; } | { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; } +>d1 : { kind: string; pos: { x: number; y: number; a?: never; b?: never; }; } | { kind: string; pos: { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; }; } +>pos : { x: number; y: number; a?: never; b?: never; } | { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; } >x : number | undefined d1.pos.y; >d1.pos.y : number | undefined ->d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; } ->d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; } ->pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; } +>d1.pos : { x: number; y: number; a?: never; b?: never; } | { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; } +>d1 : { kind: string; pos: { x: number; y: number; a?: never; b?: never; }; } | { kind: string; pos: { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; }; } +>pos : { x: number; y: number; a?: never; b?: never; } | { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; } >y : number | undefined d1.pos.a; >d1.pos.a : string | undefined ->d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; } ->d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; } ->pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; } +>d1.pos : { x: number; y: number; a?: never; b?: never; } | { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; } +>d1 : { kind: string; pos: { x: number; y: number; a?: never; b?: never; }; } | { kind: string; pos: { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; }; } +>pos : { x: number; y: number; a?: never; b?: never; } | { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; } >a : string | undefined d1.pos.b; >d1.pos.b : number | undefined ->d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; } ->d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; } ->pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; } +>d1.pos : { x: number; y: number; a?: never; b?: never; } | { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; } +>d1 : { kind: string; pos: { x: number; y: number; a?: never; b?: never; }; } | { kind: string; pos: { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; }; } +>pos : { x: number; y: number; a?: never; b?: never; } | { a: string; x?: never; y?: never; b?: never; } | { b: number; x?: never; y?: never; a?: never; } >b : number | undefined declare function f(...items: T[]): T; @@ -276,8 +276,8 @@ declare let data: { a: 1, b: "abc", c: true }; // Object literals are inferred as a single normalized union type let e1 = f({ a: 1, b: 2 }, { a: "abc" }, {}); ->e1 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; } ->f({ a: 1, b: 2 }, { a: "abc" }, {}) : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; } +>e1 : { a: number; b: number; } | { a: string; b?: never; } | { a?: never; b?: never; } +>f({ a: 1, b: 2 }, { a: "abc" }, {}) : { a: number; b: number; } | { a: string; b?: never; } | { a?: never; b?: never; } >f : (...items: T[]) => T >{ a: 1, b: 2 } : { a: number; b: number; } >a : number @@ -290,8 +290,8 @@ let e1 = f({ a: 1, b: 2 }, { a: "abc" }, {}); >{} : {} let e2 = f({}, { a: "abc" }, { a: 1, b: 2 }); ->e2 : { a?: undefined; b?: undefined; } | { a: string; b?: undefined; } | { a: number; b: number; } ->f({}, { a: "abc" }, { a: 1, b: 2 }) : { a?: undefined; b?: undefined; } | { a: string; b?: undefined; } | { a: number; b: number; } +>e2 : { a?: never; b?: never; } | { a: string; b?: never; } | { a: number; b: number; } +>f({}, { a: "abc" }, { a: 1, b: 2 }) : { a?: never; b?: never; } | { a: string; b?: never; } | { a: number; b: number; } >f : (...items: T[]) => T >{} : {} >{ a: "abc" } : { a: string; } diff --git a/tests/baselines/reference/objectSpreadRepeatedComplexity.types b/tests/baselines/reference/objectSpreadRepeatedComplexity.types index 376a7db385ea6..ad44309a2177d 100644 --- a/tests/baselines/reference/objectSpreadRepeatedComplexity.types +++ b/tests/baselines/reference/objectSpreadRepeatedComplexity.types @@ -1,11 +1,11 @@ === tests/cases/conformance/types/spread/objectSpreadRepeatedComplexity.ts === function f(cnd: Record){ ->f : (cnd: Record) => { prop20a?: number | undefined; prop20b?: number | undefined; prop19a?: number | undefined; prop19b?: number | undefined; prop18a?: number | undefined; prop18b?: number | undefined; prop17a?: number | undefined; prop17b?: number | undefined; prop16a?: number | undefined; prop16b?: number | undefined; prop15a?: number | undefined; prop15b?: number | undefined; prop14a?: number | undefined; prop14b?: number | undefined; prop13a?: number | undefined; prop13b?: number | undefined; prop12a?: number | undefined; prop12b?: number | undefined; prop11a?: number | undefined; prop11b?: number | undefined; prop10a?: number | undefined; prop10b?: number | undefined; prop9a?: number | undefined; prop9b?: number | undefined; prop8a?: number | undefined; prop8b?: number | undefined; prop7a?: number | undefined; prop7b?: number | undefined; prop6a?: number | undefined; prop6b?: number | undefined; prop5a?: number | undefined; prop5b?: number | undefined; prop4a?: number | undefined; prop4b?: number | undefined; prop3a?: number | undefined; prop3b?: number | undefined; prop0?: number | undefined; } +>f : (cnd: Record) => { prop20a?: number; prop20b?: number; prop19a?: number; prop19b?: number; prop18a?: number; prop18b?: number; prop17a?: number; prop17b?: number; prop16a?: number; prop16b?: number; prop15a?: number; prop15b?: number; prop14a?: number; prop14b?: number; prop13a?: number; prop13b?: number; prop12a?: number; prop12b?: number; prop11a?: number; prop11b?: number; prop10a?: number; prop10b?: number; prop9a?: number; prop9b?: number; prop8a?: number; prop8b?: number; prop7a?: number; prop7b?: number; prop6a?: number; prop6b?: number; prop5a?: number; prop5b?: number; prop4a?: number; prop4b?: number; prop3a?: number; prop3b?: number; prop0?: number; } >cnd : Record // Type is a union of 2^(n-1) members, where n is the number of spread objects return { ->{ // Without this one, it collapses to {} ? ...(cnd[1] && cnd[2] && { prop0: 0, }), // With one prop each, it collapses to a single object (#34853?) ...(cnd[3] && { prop3a: 1, prop3b: 1, }), ...(cnd[4] && { prop4a: 1, prop4b: 1, }), ...(cnd[5] && { prop5a: 1, prop5b: 1, }), ...(cnd[6] && { prop6a: 1, prop6b: 1, }), ...(cnd[7] && { prop7a: 1, prop7b: 1, }), ...(cnd[8] && { prop8a: 1, prop8b: 1, }), ...(cnd[9] && { prop9a: 1, prop9b: 1, }), ...(cnd[10] && { prop10a: 1, prop10b: 1, }), ...(cnd[11] && { prop11a: 1, prop11b: 1, }), ...(cnd[12] && { prop12a: 1, prop12b: 1, }), ...(cnd[13] && { prop13a: 1, prop13b: 1, }), ...(cnd[14] && { prop14a: 1, prop14b: 1, }), ...(cnd[15] && { prop15a: 1, prop15b: 1, }), ...(cnd[16] && { prop16a: 1, prop16b: 1, }), ...(cnd[17] && { prop17a: 1, prop17b: 1, }), ...(cnd[18] && { prop18a: 1, prop18b: 1, }), ...(cnd[19] && { prop19a: 1, prop19b: 1, }), ...(cnd[20] && { prop20a: 1, prop20b: 1, }), } : { prop20a?: number | undefined; prop20b?: number | undefined; prop19a?: number | undefined; prop19b?: number | undefined; prop18a?: number | undefined; prop18b?: number | undefined; prop17a?: number | undefined; prop17b?: number | undefined; prop16a?: number | undefined; prop16b?: number | undefined; prop15a?: number | undefined; prop15b?: number | undefined; prop14a?: number | undefined; prop14b?: number | undefined; prop13a?: number | undefined; prop13b?: number | undefined; prop12a?: number | undefined; prop12b?: number | undefined; prop11a?: number | undefined; prop11b?: number | undefined; prop10a?: number | undefined; prop10b?: number | undefined; prop9a?: number | undefined; prop9b?: number | undefined; prop8a?: number | undefined; prop8b?: number | undefined; prop7a?: number | undefined; prop7b?: number | undefined; prop6a?: number | undefined; prop6b?: number | undefined; prop5a?: number | undefined; prop5b?: number | undefined; prop4a?: number | undefined; prop4b?: number | undefined; prop3a?: number | undefined; prop3b?: number | undefined; prop0?: number | undefined; } +>{ // Without this one, it collapses to {} ? ...(cnd[1] && cnd[2] && { prop0: 0, }), // With one prop each, it collapses to a single object (#34853?) ...(cnd[3] && { prop3a: 1, prop3b: 1, }), ...(cnd[4] && { prop4a: 1, prop4b: 1, }), ...(cnd[5] && { prop5a: 1, prop5b: 1, }), ...(cnd[6] && { prop6a: 1, prop6b: 1, }), ...(cnd[7] && { prop7a: 1, prop7b: 1, }), ...(cnd[8] && { prop8a: 1, prop8b: 1, }), ...(cnd[9] && { prop9a: 1, prop9b: 1, }), ...(cnd[10] && { prop10a: 1, prop10b: 1, }), ...(cnd[11] && { prop11a: 1, prop11b: 1, }), ...(cnd[12] && { prop12a: 1, prop12b: 1, }), ...(cnd[13] && { prop13a: 1, prop13b: 1, }), ...(cnd[14] && { prop14a: 1, prop14b: 1, }), ...(cnd[15] && { prop15a: 1, prop15b: 1, }), ...(cnd[16] && { prop16a: 1, prop16b: 1, }), ...(cnd[17] && { prop17a: 1, prop17b: 1, }), ...(cnd[18] && { prop18a: 1, prop18b: 1, }), ...(cnd[19] && { prop19a: 1, prop19b: 1, }), ...(cnd[20] && { prop20a: 1, prop20b: 1, }), } : { prop20a?: number; prop20b?: number; prop19a?: number; prop19b?: number; prop18a?: number; prop18b?: number; prop17a?: number; prop17b?: number; prop16a?: number; prop16b?: number; prop15a?: number; prop15b?: number; prop14a?: number; prop14b?: number; prop13a?: number; prop13b?: number; prop12a?: number; prop12b?: number; prop11a?: number; prop11b?: number; prop10a?: number; prop10b?: number; prop9a?: number; prop9b?: number; prop8a?: number; prop8b?: number; prop7a?: number; prop7b?: number; prop6a?: number; prop6b?: number; prop5a?: number; prop5b?: number; prop4a?: number; prop4b?: number; prop3a?: number; prop3b?: number; prop0?: number; } // Without this one, it collapses to {} ? ...(cnd[1] && diff --git a/tests/baselines/reference/objectSpreadRepeatedNullCheckPerf.types b/tests/baselines/reference/objectSpreadRepeatedNullCheckPerf.types index 12f4789c3e390..d2f1e79037175 100644 --- a/tests/baselines/reference/objectSpreadRepeatedNullCheckPerf.types +++ b/tests/baselines/reference/objectSpreadRepeatedNullCheckPerf.types @@ -84,7 +84,7 @@ function parseWithSpread(config: Record): Props { >config : Record return { ->{ ...config.a !== undefined && { a: config.a.toString() }, ...config.b !== undefined && { b: config.b.toString() }, ...config.c !== undefined && { c: config.c.toString() }, ...config.d !== undefined && { d: config.d.toString() }, ...config.e !== undefined && { e: config.e.toString() }, ...config.f !== undefined && { f: config.f.toString() }, ...config.g !== undefined && { g: config.g.toString() }, ...config.h !== undefined && { h: config.h.toString() }, ...config.i !== undefined && { i: config.i.toString() }, ...config.j !== undefined && { j: config.j.toString() }, ...config.k !== undefined && { k: config.k.toString() }, ...config.l !== undefined && { l: config.l.toString() }, ...config.m !== undefined && { m: config.m.toString() }, ...config.n !== undefined && { n: config.n.toString() }, ...config.o !== undefined && { o: config.o.toString() }, ...config.p !== undefined && { p: config.p.toString() }, ...config.q !== undefined && { q: config.q.toString() }, ...config.r !== undefined && { r: config.r.toString() }, ...config.s !== undefined && { s: config.s.toString() }, ...config.t !== undefined && { t: config.t.toString() }, ...config.u !== undefined && { u: config.u.toString() }, ...config.v !== undefined && { v: config.v.toString() }, ...config.w !== undefined && { w: config.w.toString() }, ...config.x !== undefined && { x: config.x.toString() }, ...config.y !== undefined && { y: config.y.toString() }, ...config.z !== undefined && { z: config.z.toString() } } : { z?: string | undefined; y?: string | undefined; x?: string | undefined; w?: string | undefined; v?: string | undefined; u?: string | undefined; t?: string | undefined; s?: string | undefined; r?: string | undefined; q?: string | undefined; p?: string | undefined; o?: string | undefined; n?: string | undefined; m?: string | undefined; l?: string | undefined; k?: string | undefined; j?: string | undefined; i?: string | undefined; h?: string | undefined; g?: string | undefined; f?: string | undefined; e?: string | undefined; d?: string | undefined; c?: string | undefined; b?: string | undefined; a?: string | undefined; } +>{ ...config.a !== undefined && { a: config.a.toString() }, ...config.b !== undefined && { b: config.b.toString() }, ...config.c !== undefined && { c: config.c.toString() }, ...config.d !== undefined && { d: config.d.toString() }, ...config.e !== undefined && { e: config.e.toString() }, ...config.f !== undefined && { f: config.f.toString() }, ...config.g !== undefined && { g: config.g.toString() }, ...config.h !== undefined && { h: config.h.toString() }, ...config.i !== undefined && { i: config.i.toString() }, ...config.j !== undefined && { j: config.j.toString() }, ...config.k !== undefined && { k: config.k.toString() }, ...config.l !== undefined && { l: config.l.toString() }, ...config.m !== undefined && { m: config.m.toString() }, ...config.n !== undefined && { n: config.n.toString() }, ...config.o !== undefined && { o: config.o.toString() }, ...config.p !== undefined && { p: config.p.toString() }, ...config.q !== undefined && { q: config.q.toString() }, ...config.r !== undefined && { r: config.r.toString() }, ...config.s !== undefined && { s: config.s.toString() }, ...config.t !== undefined && { t: config.t.toString() }, ...config.u !== undefined && { u: config.u.toString() }, ...config.v !== undefined && { v: config.v.toString() }, ...config.w !== undefined && { w: config.w.toString() }, ...config.x !== undefined && { x: config.x.toString() }, ...config.y !== undefined && { y: config.y.toString() }, ...config.z !== undefined && { z: config.z.toString() } } : { z?: string; y?: string; x?: string; w?: string; v?: string; u?: string; t?: string; s?: string; r?: string; q?: string; p?: string; o?: string; n?: string; m?: string; l?: string; k?: string; j?: string; i?: string; h?: string; g?: string; f?: string; e?: string; d?: string; c?: string; b?: string; a?: string; } ...config.a !== undefined && { a: config.a.toString() }, >config.a !== undefined && { a: config.a.toString() } : false | { a: string; } diff --git a/tests/baselines/reference/omitTypeHelperModifiers01.errors.txt b/tests/baselines/reference/omitTypeHelperModifiers01.errors.txt index e175a53703230..0094f0e8d6ba5 100644 --- a/tests/baselines/reference/omitTypeHelperModifiers01.errors.txt +++ b/tests/baselines/reference/omitTypeHelperModifiers01.errors.txt @@ -1,7 +1,8 @@ +tests/cases/compiler/omitTypeHelperModifiers01.ts(13,5): error TS2322: Type 'undefined' is not assignable to type 'string'. tests/cases/compiler/omitTypeHelperModifiers01.ts(16,7): error TS2540: Cannot assign to 'c' because it is a read-only property. -==== tests/cases/compiler/omitTypeHelperModifiers01.ts (1 errors) ==== +==== tests/cases/compiler/omitTypeHelperModifiers01.ts (2 errors) ==== type A = { a: number; b?: string; @@ -15,6 +16,8 @@ tests/cases/compiler/omitTypeHelperModifiers01.ts(16,7): error TS2540: Cannot as const b = x.b; x.b = "hello"; x.b = undefined; + ~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. const c = x.c; x.c = true; diff --git a/tests/baselines/reference/omitTypeHelperModifiers01.types b/tests/baselines/reference/omitTypeHelperModifiers01.types index b1962065e4b8c..37575cecd4f0f 100644 --- a/tests/baselines/reference/omitTypeHelperModifiers01.types +++ b/tests/baselines/reference/omitTypeHelperModifiers01.types @@ -31,16 +31,16 @@ function f(x: B) { x.b = "hello"; >x.b = "hello" : "hello" ->x.b : string | undefined +>x.b : string >x : B ->b : string | undefined +>b : string >"hello" : "hello" x.b = undefined; >x.b = undefined : undefined ->x.b : string | undefined +>x.b : string >x : B ->b : string | undefined +>b : string >undefined : undefined const c = x.c; diff --git a/tests/baselines/reference/optionalPropertyAssignableToStringIndexSignature.errors.txt b/tests/baselines/reference/optionalPropertyAssignableToStringIndexSignature.errors.txt index f6ba165804206..130557d978e21 100644 --- a/tests/baselines/reference/optionalPropertyAssignableToStringIndexSignature.errors.txt +++ b/tests/baselines/reference/optionalPropertyAssignableToStringIndexSignature.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/optional Property 'k1' is incompatible with index signature. Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'. -tests/cases/conformance/types/typeRelationships/assignmentCompatibility/optionalPropertyAssignableToStringIndexSignature.ts(10,1): error TS2322: Type '{ 1?: string | undefined; }' is not assignable to type '{ [key: number]: string; }'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/optionalPropertyAssignableToStringIndexSignature.ts(10,1): error TS2322: Type '{ 1?: string; }' is not assignable to type '{ [key: number]: string; }'. Property '1' is incompatible with index signature. Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'. @@ -28,7 +28,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/optional declare let numberLiteralKeys: { 1?: string }; probablyArray = numberLiteralKeys; // error ~~~~~~~~~~~~~ -!!! error TS2322: Type '{ 1?: string | undefined; }' is not assignable to type '{ [key: number]: string; }'. +!!! error TS2322: Type '{ 1?: string; }' is not assignable to type '{ [key: number]: string; }'. !!! error TS2322: Property '1' is incompatible with index signature. !!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. !!! error TS2322: Type 'undefined' is not assignable to type 'string'. diff --git a/tests/baselines/reference/optionalPropertyAssignableToStringIndexSignature.types b/tests/baselines/reference/optionalPropertyAssignableToStringIndexSignature.types index 1a8859b6e781f..b9154db8964c4 100644 --- a/tests/baselines/reference/optionalPropertyAssignableToStringIndexSignature.types +++ b/tests/baselines/reference/optionalPropertyAssignableToStringIndexSignature.types @@ -1,6 +1,6 @@ === tests/cases/conformance/types/typeRelationships/assignmentCompatibility/optionalPropertyAssignableToStringIndexSignature.ts === declare let optionalProperties: { k1?: string }; ->optionalProperties : { k1?: string | undefined; } +>optionalProperties : { k1?: string; } >k1 : string | undefined declare let undefinedProperties: { k1: string | undefined }; @@ -12,9 +12,9 @@ declare let stringDictionary: { [key: string]: string }; >key : string stringDictionary = optionalProperties; // ok ->stringDictionary = optionalProperties : { k1?: string | undefined; } +>stringDictionary = optionalProperties : { k1?: string; } >stringDictionary : { [key: string]: string; } ->optionalProperties : { k1?: string | undefined; } +>optionalProperties : { k1?: string; } stringDictionary = undefinedProperties; // error >stringDictionary = undefinedProperties : { k1: string | undefined; } @@ -26,13 +26,13 @@ declare let probablyArray: { [key: number]: string }; >key : number declare let numberLiteralKeys: { 1?: string }; ->numberLiteralKeys : { 1?: string | undefined; } +>numberLiteralKeys : { 1?: string; } >1 : string | undefined probablyArray = numberLiteralKeys; // error ->probablyArray = numberLiteralKeys : { 1?: string | undefined; } +>probablyArray = numberLiteralKeys : { 1?: string; } >probablyArray : { [key: number]: string; } ->numberLiteralKeys : { 1?: string | undefined; } +>numberLiteralKeys : { 1?: string; } declare let optionalUndefined: { k1?: undefined }; >optionalUndefined : { k1?: undefined; } @@ -47,7 +47,7 @@ function f() { >f : () => void let optional: { k1?: T } = undefined!; ->optional : { k1?: T | undefined; } +>optional : { k1?: T; } >k1 : T | undefined >undefined! : never >undefined : undefined @@ -55,6 +55,6 @@ function f() { let dict: { [key: string]: T | number } = optional; // ok >dict : { [key: string]: number | T; } >key : string ->optional : { k1?: T | undefined; } +>optional : { k1?: T; } } diff --git a/tests/baselines/reference/optionalTupleElements1.types b/tests/baselines/reference/optionalTupleElements1.types index b784bf72e5843..980e1a3b98d54 100644 --- a/tests/baselines/reference/optionalTupleElements1.types +++ b/tests/baselines/reference/optionalTupleElements1.types @@ -138,9 +138,9 @@ t3 = [42, "hello"]; >"hello" : "hello" t3 = [42,,true] ->t3 = [42,,true] : [number, undefined, true] +>t3 = [42,,true] : [number, never?, true?] >t3 : T3 ->[42,,true] : [number, undefined, true] +>[42,,true] : [number, never?, true?] >42 : 42 > : undefined >true : true @@ -159,25 +159,25 @@ t4 = [42, "hello"]; >"hello" : "hello" t4 = [42,,true]; ->t4 = [42,,true] : [number, undefined, true] +>t4 = [42,,true] : [number, never?, true?] >t4 : T4 ->[42,,true] : [number, undefined, true] +>[42,,true] : [number, never?, true?] >42 : 42 > : undefined >true : true t4 = [,"hello", true]; ->t4 = [,"hello", true] : [undefined, string, true] +>t4 = [,"hello", true] : [never?, string?, true?] >t4 : T4 ->[,"hello", true] : [undefined, string, true] +>[,"hello", true] : [never?, string?, true?] > : undefined >"hello" : "hello" >true : true t4 = [,,true]; ->t4 = [,,true] : [undefined, undefined, true] +>t4 = [,,true] : [never?, never?, true?] >t4 : T4 ->[,,true] : [undefined, undefined, true] +>[,,true] : [never?, never?, true?] > : undefined > : undefined >true : true diff --git a/tests/baselines/reference/paramsOnlyHaveLiteralTypesWhenAppropriatelyContextualized.errors.txt b/tests/baselines/reference/paramsOnlyHaveLiteralTypesWhenAppropriatelyContextualized.errors.txt index 4304bb486ef0e..8120d68d750b3 100644 --- a/tests/baselines/reference/paramsOnlyHaveLiteralTypesWhenAppropriatelyContextualized.errors.txt +++ b/tests/baselines/reference/paramsOnlyHaveLiteralTypesWhenAppropriatelyContextualized.errors.txt @@ -1,13 +1,11 @@ -tests/cases/compiler/paramsOnlyHaveLiteralTypesWhenAppropriatelyContextualized.ts(27,23): error TS2345: Argument of type '{ x?: number[] | undefined; y?: string[] | undefined; }' is not assignable to parameter of type '{ y?: number[] | undefined; }'. +tests/cases/compiler/paramsOnlyHaveLiteralTypesWhenAppropriatelyContextualized.ts(27,23): error TS2345: Argument of type '{ x?: number[]; y?: string[]; }' is not assignable to parameter of type '{ y?: number[]; }'. Types of property 'y' are incompatible. - Type 'string[] | undefined' is not assignable to type 'number[] | undefined'. - Type 'string[]' is not assignable to type 'number[]'. - Type 'string' is not assignable to type 'number'. -tests/cases/compiler/paramsOnlyHaveLiteralTypesWhenAppropriatelyContextualized.ts(28,23): error TS2345: Argument of type '{ x?: number[] | undefined; y?: string[] | undefined; }' is not assignable to parameter of type '{ x?: string[] | undefined; }'. + Type 'string[]' is not assignable to type 'number[]'. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/paramsOnlyHaveLiteralTypesWhenAppropriatelyContextualized.ts(28,23): error TS2345: Argument of type '{ x?: number[]; y?: string[]; }' is not assignable to parameter of type '{ x?: string[]; }'. Types of property 'x' are incompatible. - Type 'number[] | undefined' is not assignable to type 'string[] | undefined'. - Type 'number[]' is not assignable to type 'string[]'. - Type 'number' is not assignable to type 'string'. + Type 'number[]' is not assignable to type 'string[]'. + Type 'number' is not assignable to type 'string'. ==== tests/cases/compiler/paramsOnlyHaveLiteralTypesWhenAppropriatelyContextualized.ts (2 errors) ==== @@ -39,15 +37,13 @@ tests/cases/compiler/paramsOnlyHaveLiteralTypesWhenAppropriatelyContextualized.t appendToOptionalArray(foo, 'y', 'bar'); // ok appendToOptionalArray(foo, 'y', 12); // should fail ~~~ -!!! error TS2345: Argument of type '{ x?: number[] | undefined; y?: string[] | undefined; }' is not assignable to parameter of type '{ y?: number[] | undefined; }'. +!!! error TS2345: Argument of type '{ x?: number[]; y?: string[]; }' is not assignable to parameter of type '{ y?: number[]; }'. !!! error TS2345: Types of property 'y' are incompatible. -!!! error TS2345: Type 'string[] | undefined' is not assignable to type 'number[] | undefined'. -!!! error TS2345: Type 'string[]' is not assignable to type 'number[]'. -!!! error TS2345: Type 'string' is not assignable to type 'number'. +!!! error TS2345: Type 'string[]' is not assignable to type 'number[]'. +!!! error TS2345: Type 'string' is not assignable to type 'number'. appendToOptionalArray(foo, 'x', "no"); // should fail ~~~ -!!! error TS2345: Argument of type '{ x?: number[] | undefined; y?: string[] | undefined; }' is not assignable to parameter of type '{ x?: string[] | undefined; }'. +!!! error TS2345: Argument of type '{ x?: number[]; y?: string[]; }' is not assignable to parameter of type '{ x?: string[]; }'. !!! error TS2345: Types of property 'x' are incompatible. -!!! error TS2345: Type 'number[] | undefined' is not assignable to type 'string[] | undefined'. -!!! error TS2345: Type 'number[]' is not assignable to type 'string[]'. -!!! error TS2345: Type 'number' is not assignable to type 'string'. \ No newline at end of file +!!! error TS2345: Type 'number[]' is not assignable to type 'string[]'. +!!! error TS2345: Type 'number' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/paramsOnlyHaveLiteralTypesWhenAppropriatelyContextualized.types b/tests/baselines/reference/paramsOnlyHaveLiteralTypesWhenAppropriatelyContextualized.types index 4e4f667b549c9..040d68293170e 100644 --- a/tests/baselines/reference/paramsOnlyHaveLiteralTypesWhenAppropriatelyContextualized.types +++ b/tests/baselines/reference/paramsOnlyHaveLiteralTypesWhenAppropriatelyContextualized.types @@ -7,13 +7,13 @@ type Lower = { [K in keyof T]: T[K] }; >Lower : Lower export function appendToOptionalArray< ->appendToOptionalArray : (object: { [x in K]?: Lower[] | undefined; }, key: K, value: T) => void +>appendToOptionalArray : (object: { [x in K]?: Lower[]; }, key: K, value: T) => void K extends string | number | symbol, T >( object: { [x in K]?: Lower[] }, ->object : { [x in K]?: Lower[] | undefined; } +>object : { [x in K]?: Lower[]; } key: K, >key : K @@ -23,13 +23,13 @@ export function appendToOptionalArray< ) { const array = object[key]; ->array : { [x in K]?: Lower[] | undefined; }[K] ->object[key] : { [x in K]?: Lower[] | undefined; }[K] ->object : { [x in K]?: Lower[] | undefined; } +>array : { [x in K]?: Lower[]; }[K] +>object[key] : { [x in K]?: Lower[]; }[K] +>object : { [x in K]?: Lower[]; } >key : K if (array) { ->array : { [x in K]?: Lower[] | undefined; }[K] +>array : { [x in K]?: Lower[]; }[K] array.push(value); >array.push(value) : number @@ -41,8 +41,8 @@ export function appendToOptionalArray< } else { object[key] = [value]; >object[key] = [value] : T[] ->object[key] : { [x in K]?: Lower[] | undefined; }[K] ->object : { [x in K]?: Lower[] | undefined; } +>object[key] : { [x in K]?: Lower[]; }[K] +>object : { [x in K]?: Lower[]; } >key : K >[value] : T[] >value : T @@ -51,36 +51,36 @@ export function appendToOptionalArray< // e.g. const foo: {x?: number[]; y?: string[]; } = {}; ->foo : { x?: number[] | undefined; y?: string[] | undefined; } +>foo : { x?: number[]; y?: string[]; } >x : number[] | undefined >y : string[] | undefined >{} : {} appendToOptionalArray(foo, 'x', 123); // ok >appendToOptionalArray(foo, 'x', 123) : void ->appendToOptionalArray : (object: { [x in K]?: Lower[] | undefined; }, key: K, value: T) => void ->foo : { x?: number[] | undefined; y?: string[] | undefined; } +>appendToOptionalArray : (object: { [x in K]?: Lower[]; }, key: K, value: T) => void +>foo : { x?: number[]; y?: string[]; } >'x' : "x" >123 : 123 appendToOptionalArray(foo, 'y', 'bar'); // ok >appendToOptionalArray(foo, 'y', 'bar') : void ->appendToOptionalArray : (object: { [x in K]?: Lower[] | undefined; }, key: K, value: T) => void ->foo : { x?: number[] | undefined; y?: string[] | undefined; } +>appendToOptionalArray : (object: { [x in K]?: Lower[]; }, key: K, value: T) => void +>foo : { x?: number[]; y?: string[]; } >'y' : "y" >'bar' : "bar" appendToOptionalArray(foo, 'y', 12); // should fail >appendToOptionalArray(foo, 'y', 12) : void ->appendToOptionalArray : (object: { [x in K]?: Lower[] | undefined; }, key: K, value: T) => void ->foo : { x?: number[] | undefined; y?: string[] | undefined; } +>appendToOptionalArray : (object: { [x in K]?: Lower[]; }, key: K, value: T) => void +>foo : { x?: number[]; y?: string[]; } >'y' : "y" >12 : 12 appendToOptionalArray(foo, 'x', "no"); // should fail >appendToOptionalArray(foo, 'x', "no") : void ->appendToOptionalArray : (object: { [x in K]?: Lower[] | undefined; }, key: K, value: T) => void ->foo : { x?: number[] | undefined; y?: string[] | undefined; } +>appendToOptionalArray : (object: { [x in K]?: Lower[]; }, key: K, value: T) => void +>foo : { x?: number[]; y?: string[]; } >'x' : "x" >"no" : "no" diff --git a/tests/baselines/reference/propTypeValidatorInference.types b/tests/baselines/reference/propTypeValidatorInference.types index be23e8eecb6cc..a04d2a0918f39 100644 --- a/tests/baselines/reference/propTypeValidatorInference.types +++ b/tests/baselines/reference/propTypeValidatorInference.types @@ -91,7 +91,7 @@ interface Props { >bool : boolean shape: { ->shape : { foo: string; bar?: boolean | undefined; baz?: any; } +>shape : { foo: string; bar?: boolean; baz?: any; } foo: string; >foo : string @@ -104,7 +104,7 @@ interface Props { }; oneOfType: string | boolean | { ->oneOfType : string | boolean | { foo?: string | undefined; bar: number; } +>oneOfType : string | boolean | { foo?: string; bar: number; } foo?: string; >foo : string | undefined diff --git a/tests/baselines/reference/propertyAccessChain.types b/tests/baselines/reference/propertyAccessChain.types index b776ca10fa28c..99c5533f1a8c7 100644 --- a/tests/baselines/reference/propertyAccessChain.types +++ b/tests/baselines/reference/propertyAccessChain.types @@ -33,39 +33,39 @@ o3.b?.c; >c : string | undefined declare const o4: { b?: { c: { d?: { e: string } } } }; ->o4 : { b?: { c: { d?: { e: string; };}; } | undefined; } +>o4 : { b?: { c: { d?: { e: string; }; };}; } >b : { c: { d?: { e: string; };}; } | undefined ->c : { d?: { e: string; } | undefined; } +>c : { d?: { e: string;}; } >d : { e: string; } | undefined >e : string o4.b?.c.d?.e; >o4.b?.c.d?.e : string | undefined >o4.b?.c.d : { e: string; } | undefined ->o4.b?.c : { d?: { e: string; } | undefined; } | undefined ->o4.b : { c: { d?: { e: string; } | undefined; }; } | undefined ->o4 : { b?: { c: { d?: { e: string; } | undefined; }; } | undefined; } ->b : { c: { d?: { e: string; } | undefined; }; } | undefined ->c : { d?: { e: string; } | undefined; } | undefined +>o4.b?.c : { d?: { e: string; }; } | undefined +>o4.b : { c: { d?: { e: string; }; }; } | undefined +>o4 : { b?: { c: { d?: { e: string; }; }; }; } +>b : { c: { d?: { e: string; }; }; } | undefined +>c : { d?: { e: string; }; } | undefined >d : { e: string; } | undefined >e : string | undefined declare const o5: { b?(): { c: { d?: { e: string } } } }; >o5 : { b?(): { c: { d?: { e: string; }; };}; } >b : (() => { c: { d?: { e: string; }; };}) | undefined ->c : { d?: { e: string; } | undefined; } +>c : { d?: { e: string;}; } >d : { e: string; } | undefined >e : string o5.b?.().c.d?.e; >o5.b?.().c.d?.e : string | undefined >o5.b?.().c.d : { e: string; } | undefined ->o5.b?.().c : { d?: { e: string; } | undefined; } | undefined ->o5.b?.() : { c: { d?: { e: string; } | undefined; }; } | undefined ->o5.b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined ->o5 : { b?(): { c: { d?: { e: string; } | undefined; }; }; } ->b : (() => { c: { d?: { e: string; } | undefined; }; }) | undefined ->c : { d?: { e: string; } | undefined; } | undefined +>o5.b?.().c : { d?: { e: string; }; } | undefined +>o5.b?.() : { c: { d?: { e: string; }; }; } | undefined +>o5.b : (() => { c: { d?: { e: string; }; }; }) | undefined +>o5 : { b?(): { c: { d?: { e: string; }; }; }; } +>b : (() => { c: { d?: { e: string; }; }; }) | undefined +>c : { d?: { e: string; }; } | undefined >d : { e: string; } | undefined >e : string | undefined diff --git a/tests/baselines/reference/reactDefaultPropsInferenceSuccess.errors.txt b/tests/baselines/reference/reactDefaultPropsInferenceSuccess.errors.txt index 335f0febc862f..edc74f9662628 100644 --- a/tests/baselines/reference/reactDefaultPropsInferenceSuccess.errors.txt +++ b/tests/baselines/reference/reactDefaultPropsInferenceSuccess.errors.txt @@ -1,23 +1,24 @@ tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx(27,36): error TS2769: No overload matches this call. Overload 1 of 2, '(props: Readonly): FieldFeedback', gave the following error. - Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'. + Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean)'. Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. Type 'void' is not assignable to type 'boolean'. Overload 2 of 2, '(props: Props, context?: any): FieldFeedback', gave the following error. - Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'. + Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean)'. + Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx(43,41): error TS2769: No overload matches this call. Overload 1 of 2, '(props: Readonly): FieldFeedbackBeta', gave the following error. - Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'. + Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean)'. Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. Type 'void' is not assignable to type 'boolean'. Overload 2 of 2, '(props: Props, context?: any): FieldFeedbackBeta', gave the following error. - Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'. -tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx(64,37): error TS2769: No overload matches this call. + Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean)'. + Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. +tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx(64,52): error TS2769: No overload matches this call. Overload 1 of 2, '(props: Readonly): FieldFeedback2', gave the following error. - Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. - Type 'void' is not assignable to type 'boolean'. + Type 'void' is not assignable to type 'boolean'. Overload 2 of 2, '(props: MyPropsProps, context?: any): FieldFeedback2', gave the following error. - Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. + Type 'void' is not assignable to type 'boolean'. ==== tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx (3 errors) ==== @@ -51,11 +52,12 @@ tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx(64,37): error TS2769: ~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(props: Readonly): FieldFeedback', gave the following error. -!!! error TS2769: Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'. +!!! error TS2769: Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean)'. !!! error TS2769: Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. !!! error TS2769: Type 'void' is not assignable to type 'boolean'. !!! error TS2769: Overload 2 of 2, '(props: Props, context?: any): FieldFeedback', gave the following error. -!!! error TS2769: Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'. +!!! error TS2769: Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean)'. +!!! error TS2769: Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. !!! related TS6500 tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx:6:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes> & Pick & Readonly, "children" | "error"> & Partial & Readonly, "when">> & Partial boolean; }, never>>' !!! related TS6500 tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx:6:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes> & Pick & Readonly, "children" | "error"> & Partial & Readonly, "when">> & Partial boolean; }, never>>' @@ -77,11 +79,12 @@ tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx(64,37): error TS2769: ~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(props: Readonly): FieldFeedbackBeta', gave the following error. -!!! error TS2769: Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'. +!!! error TS2769: Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean)'. !!! error TS2769: Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. !!! error TS2769: Type 'void' is not assignable to type 'boolean'. !!! error TS2769: Overload 2 of 2, '(props: Props, context?: any): FieldFeedbackBeta', gave the following error. -!!! error TS2769: Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'. +!!! error TS2769: Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean)'. +!!! error TS2769: Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. !!! related TS6500 tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx:6:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes> & Pick & Readonly, "children"> & Partial & Readonly, keyof Props>> & Partial>' !!! related TS6500 tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx:6:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes> & Pick & Readonly, "children"> & Partial & Readonly, keyof Props>> & Partial>' @@ -105,15 +108,14 @@ tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx(64,37): error TS2769: // Error: Void not assignable to boolean const Test4 = () => console.log(value)} />; - ~~~~ + ~~~~~~~~~~~~~~~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(props: Readonly): FieldFeedback2', gave the following error. -!!! error TS2769: Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. -!!! error TS2769: Type 'void' is not assignable to type 'boolean'. +!!! error TS2769: Type 'void' is not assignable to type 'boolean'. !!! error TS2769: Overload 2 of 2, '(props: MyPropsProps, context?: any): FieldFeedback2', gave the following error. -!!! error TS2769: Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. -!!! related TS6500 tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx:46:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes> & Pick & Readonly, "children" | "error"> & Partial & Readonly, "when">> & Partial boolean; }, never>>' -!!! related TS6500 tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx:46:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes> & Pick & Readonly, "children" | "error"> & Partial & Readonly, "when">> & Partial boolean; }, never>>' +!!! error TS2769: Type 'void' is not assignable to type 'boolean'. +!!! related TS6502 tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx:46:9: The expected type comes from the return type of this signature. +!!! related TS6502 tests/cases/compiler/reactDefaultPropsInferenceSuccess.tsx:46:9: The expected type comes from the return type of this signature. // OK const Test5 = () => ; diff --git a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.types b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.types index 9bc29e06e9063..a6c8176e10ee1 100644 --- a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.types +++ b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.types @@ -10,7 +10,7 @@ declare class Component

{ >context : any readonly props: Readonly

& Readonly<{ children?: {} }>; ->props : Readonly

& Readonly<{ children?: {} | undefined; }> +>props : Readonly

& Readonly<{ children?: {}; }> >children : {} | undefined } interface ComponentClass

{ @@ -29,7 +29,7 @@ interface ComponentClass

{ } interface FunctionComponent

{ (props: P & { children?: {} }, context?: any): {} | null; ->props : P & { children?: {} | undefined; } +>props : P & { children?: {}; } >children : {} | undefined >context : any >null : null diff --git a/tests/baselines/reference/showConfig/Shows tsconfig for single option/strictOptionalProperties/tsconfig.json b/tests/baselines/reference/showConfig/Shows tsconfig for single option/strictOptionalProperties/tsconfig.json new file mode 100644 index 0000000000000..dd668491808c4 --- /dev/null +++ b/tests/baselines/reference/showConfig/Shows tsconfig for single option/strictOptionalProperties/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "strictOptionalProperties": true + } +} diff --git a/tests/baselines/reference/spreadIdenticalTypesRemoved.types b/tests/baselines/reference/spreadIdenticalTypesRemoved.types index 6695770ccc3ed..42d7006306b82 100644 --- a/tests/baselines/reference/spreadIdenticalTypesRemoved.types +++ b/tests/baselines/reference/spreadIdenticalTypesRemoved.types @@ -17,12 +17,12 @@ interface Animal { } function clonePet(pet: Animal, fullCopy?: boolean) { ->clonePet : (pet: Animal, fullCopy?: boolean | undefined) => { name: string; kind: string; age?: number | undefined; location?: string | undefined; owner?: object | undefined; } +>clonePet : (pet: Animal, fullCopy?: boolean | undefined) => { name: string; kind: string; age?: number; location?: string; owner?: object; } >pet : Animal >fullCopy : boolean | undefined return { ->{ name: pet.name, kind: pet.kind, ...(fullCopy && pet), } : { name: string; kind: string; age?: number | undefined; location?: string | undefined; owner?: object | undefined; } +>{ name: pet.name, kind: pet.kind, ...(fullCopy && pet), } : { name: string; kind: string; age?: number; location?: string; owner?: object; } name: pet.name, >name : string @@ -52,11 +52,11 @@ interface Animal2 { >owner : string | undefined } function billOwner(pet: Animal2) { ->billOwner : (pet: Animal2) => { paid: boolean; name?: string | undefined; owner?: string | undefined; } +>billOwner : (pet: Animal2) => { paid: boolean; name?: string; owner?: string; } >pet : Animal2 return { ->{ ...(pet.owner && pet), paid: false } : { paid: boolean; name?: string | undefined; owner?: string | undefined; } +>{ ...(pet.owner && pet), paid: false } : { paid: boolean; name?: string; owner?: string; } ...(pet.owner && pet), >(pet.owner && pet) : "" | Animal2 | undefined diff --git a/tests/baselines/reference/spreadOfObjectLiteralAssignableToIndexSignature.types b/tests/baselines/reference/spreadOfObjectLiteralAssignableToIndexSignature.types index 8b4fd5422a738..53462c68c03ea 100644 --- a/tests/baselines/reference/spreadOfObjectLiteralAssignableToIndexSignature.types +++ b/tests/baselines/reference/spreadOfObjectLiteralAssignableToIndexSignature.types @@ -9,11 +9,11 @@ const recordOfRecords: RecordOfRecords = {} >{} : {} recordOfRecords.propA = {...(foo !== undefined ? {foo} : {})} // OK ->recordOfRecords.propA = {...(foo !== undefined ? {foo} : {})} : { foo?: Record | undefined; } +>recordOfRecords.propA = {...(foo !== undefined ? {foo} : {})} : { foo?: Record; } >recordOfRecords.propA : RecordOfRecords >recordOfRecords : RecordOfRecords >propA : RecordOfRecords ->{...(foo !== undefined ? {foo} : {})} : { foo?: Record | undefined; } +>{...(foo !== undefined ? {foo} : {})} : { foo?: Record; } >(foo !== undefined ? {foo} : {}) : { foo: Record; } | {} >foo !== undefined ? {foo} : {} : { foo: Record; } | {} >foo !== undefined : boolean @@ -36,11 +36,11 @@ recordOfRecords.propB = {...(foo && {foo})} // OK >foo : Record recordOfRecords.propC = {...(foo !== undefined && {foo})} // error'd in 3.7 beta, should be OK ->recordOfRecords.propC = {...(foo !== undefined && {foo})} : { foo?: Record | undefined; } +>recordOfRecords.propC = {...(foo !== undefined && {foo})} : { foo?: Record; } >recordOfRecords.propC : RecordOfRecords >recordOfRecords : RecordOfRecords >propC : RecordOfRecords ->{...(foo !== undefined && {foo})} : { foo?: Record | undefined; } +>{...(foo !== undefined && {foo})} : { foo?: Record; } >(foo !== undefined && {foo}) : false | { foo: Record; } >foo !== undefined && {foo} : false | { foo: Record; } >foo !== undefined : boolean @@ -55,11 +55,11 @@ const recordsOfRecordsOrEmpty: RecordOfRecordsOrEmpty = {} >{} : {} recordsOfRecordsOrEmpty.propA = {...(foo !== undefined ? {foo} : {})} // OK ->recordsOfRecordsOrEmpty.propA = {...(foo !== undefined ? {foo} : {})} : { foo?: Record | undefined; } +>recordsOfRecordsOrEmpty.propA = {...(foo !== undefined ? {foo} : {})} : { foo?: Record; } >recordsOfRecordsOrEmpty.propA : {} | RecordOfRecordsOrEmpty >recordsOfRecordsOrEmpty : RecordOfRecordsOrEmpty >propA : {} | RecordOfRecordsOrEmpty ->{...(foo !== undefined ? {foo} : {})} : { foo?: Record | undefined; } +>{...(foo !== undefined ? {foo} : {})} : { foo?: Record; } >(foo !== undefined ? {foo} : {}) : { foo: Record; } | {} >foo !== undefined ? {foo} : {} : { foo: Record; } | {} >foo !== undefined : boolean @@ -82,11 +82,11 @@ recordsOfRecordsOrEmpty.propB = {...(foo && {foo})} // OK >foo : Record recordsOfRecordsOrEmpty.propC = {...(foo !== undefined && {foo})} // OK ->recordsOfRecordsOrEmpty.propC = {...(foo !== undefined && {foo})} : { foo?: Record | undefined; } +>recordsOfRecordsOrEmpty.propC = {...(foo !== undefined && {foo})} : { foo?: Record; } >recordsOfRecordsOrEmpty.propC : {} | RecordOfRecordsOrEmpty >recordsOfRecordsOrEmpty : RecordOfRecordsOrEmpty >propC : {} | RecordOfRecordsOrEmpty ->{...(foo !== undefined && {foo})} : { foo?: Record | undefined; } +>{...(foo !== undefined && {foo})} : { foo?: Record; } >(foo !== undefined && {foo}) : false | { foo: Record; } >foo !== undefined && {foo} : false | { foo: Record; } >foo !== undefined : boolean diff --git a/tests/baselines/reference/spreadOverwritesPropertyStrict.types b/tests/baselines/reference/spreadOverwritesPropertyStrict.types index 62a109a410f9a..9ecf3c2b94e22 100644 --- a/tests/baselines/reference/spreadOverwritesPropertyStrict.types +++ b/tests/baselines/reference/spreadOverwritesPropertyStrict.types @@ -5,7 +5,7 @@ declare var ab: { a: number, b: number }; >b : number declare var abq: { a: number, b?: number }; ->abq : { a: number; b?: number | undefined; } +>abq : { a: number; b?: number; } >a : number >b : number | undefined @@ -27,7 +27,7 @@ var unused3 = { b: 1, ...abq } // ok, abq might have b: undefined >{ b: 1, ...abq } : { a: number; b: number; } >b : number >1 : 1 ->abq : { a: number; b?: number | undefined; } +>abq : { a: number; b?: number; } var unused4 = { ...ab, b: 1 } // ok, we don't care that b in ab is overwritten >unused4 : { b: number; a: number; } @@ -39,7 +39,7 @@ var unused4 = { ...ab, b: 1 } // ok, we don't care that b in ab is overwritten var unused5 = { ...abq, b: 1 } // ok >unused5 : { b: number; a: number; } >{ ...abq, b: 1 } : { b: number; a: number; } ->abq : { a: number; b?: number | undefined; } +>abq : { a: number; b?: number; } >b : number >1 : 1 @@ -78,14 +78,14 @@ function h(obj: { x: number } | { x: string }) { >obj : { x: number; } | { x: string; } } function i(b: boolean, t: { command: string, ok: string }) { ->i : (b: boolean, t: { command: string; ok: string;}) => { command: string; ok?: string | undefined; } +>i : (b: boolean, t: { command: string; ok: string;}) => { command: string; ok?: string; } >b : boolean >t : { command: string; ok: string; } >command : string >ok : string return { command: "hi", ...(b ? t : {}) } // ok ->{ command: "hi", ...(b ? t : {}) } : { command: string; ok?: string | undefined; } +>{ command: "hi", ...(b ? t : {}) } : { command: string; ok?: string; } >command : string >"hi" : "hi" >(b ? t : {}) : { command: string; ok: string; } | {} diff --git a/tests/baselines/reference/strictOptionalProperties1.errors.txt b/tests/baselines/reference/strictOptionalProperties1.errors.txt new file mode 100644 index 0000000000000..9d6fd76f53431 --- /dev/null +++ b/tests/baselines/reference/strictOptionalProperties1.errors.txt @@ -0,0 +1,185 @@ +tests/cases/compiler/strictOptionalProperties1.ts(6,5): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/compiler/strictOptionalProperties1.ts(12,5): error TS2322: Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/compiler/strictOptionalProperties1.ts(20,9): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/compiler/strictOptionalProperties1.ts(28,9): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/compiler/strictOptionalProperties1.ts(53,5): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/compiler/strictOptionalProperties1.ts(60,5): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/compiler/strictOptionalProperties1.ts(64,5): error TS2322: Type '[number, string?, string?]' is not assignable to type '[number, string?]'. + Target allows only 2 element(s) but source may have more. +tests/cases/compiler/strictOptionalProperties1.ts(73,5): error TS2322: Type '[number, never?, never?, never?]' is not assignable to type '[number, string?, boolean?]'. + Target allows only 3 element(s) but source may have more. +tests/cases/compiler/strictOptionalProperties1.ts(74,5): error TS2322: Type '[never?, never?, true?]' is not assignable to type '[number, string?, boolean?]'. + Source provides no match for required element at position 0 in target. +tests/cases/compiler/strictOptionalProperties1.ts(75,14): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/compiler/strictOptionalProperties1.ts(99,34): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/compiler/strictOptionalProperties1.ts(105,45): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/compiler/strictOptionalProperties1.ts(106,55): error TS2322: Type 'undefined' is not assignable to type 'boolean'. +tests/cases/compiler/strictOptionalProperties1.ts(107,45): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/compiler/strictOptionalProperties1.ts(107,56): error TS2322: Type 'undefined' is not assignable to type 'boolean'. +tests/cases/compiler/strictOptionalProperties1.ts(111,31): error TS2322: Type 'undefined' is not assignable to type 'number'. +tests/cases/compiler/strictOptionalProperties1.ts(119,5): error TS2411: Property 'bar' of type 'string | undefined' is not assignable to string index type 'string'. + + +==== tests/cases/compiler/strictOptionalProperties1.ts (17 errors) ==== + function f1(obj: { a?: string, b?: string | undefined }) { + let a = obj.a; // string | undefined + let b = obj.b; // string | undefined + obj.a = 'hello'; + obj.b = 'hello'; + obj.a = undefined; // Error + ~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + obj.b = undefined; + } + + function f2(obj: { a?: string, b?: string | undefined }) { + obj = obj; + obj.a = obj.a; // Error + ~~~~~ +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + obj.b = obj.b; + if ('a' in obj) { + obj.a; + obj.a = obj.a; + } + else { + obj.a; + obj.a = obj.a; // Error + ~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + } + if (obj.hasOwnProperty('a')) { + obj.a; + obj.a = obj.a; + } + else { + obj.a; + obj.a = obj.a; // Error + ~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + } + if ('b' in obj) { + obj.b; + obj.b = obj.b; + } + else { + obj.b; + obj.b = obj.b; + } + if (obj.hasOwnProperty('b')) { + obj.b; + obj.b = obj.b; + } + else { + obj.b; + obj.b = obj.b; + } + } + + function f3(obj: Partial<{ a: string, b: string | undefined }>) { + let a = obj.a; // string | undefined + let b = obj.b; // string | undefined + obj.a = 'hello'; + obj.b = 'hello'; + obj.a = undefined; // Error + ~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + obj.b = undefined; + } + + function f4(t: [string?]) { + let x = t[0]; // string | undefined + t[0] = 'hello'; + t[0] = undefined; // Error + ~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + } + + function f4a(t1: [number, string?], t2: [number, string?, string?]) { + t1 = t2; // Wasn't an error, but should be + ~~ +!!! error TS2322: Type '[number, string?, string?]' is not assignable to type '[number, string?]'. +!!! error TS2322: Target allows only 2 element(s) but source may have more. + } + + function f5(t: [number, string?, boolean?]) { + t = [42]; + t = [42, 'abc']; + t = [42, 'abc', true]; + t = [42, ,]; + t = [42, , ,]; + t = [42, , , ,]; // Error + ~ +!!! error TS2322: Type '[number, never?, never?, never?]' is not assignable to type '[number, string?, boolean?]'. +!!! error TS2322: Target allows only 3 element(s) but source may have more. + t = [, , true]; // Error + ~ +!!! error TS2322: Type '[never?, never?, true?]' is not assignable to type '[number, string?, boolean?]'. +!!! error TS2322: Source provides no match for required element at position 0 in target. + t = [42, undefined, true]; // Error + ~~~~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + } + + function f6() { + const t1 = [1, 2] as const; + const t2 = [1, 2, ,] as const; + const t3 = [1, 2, , ,] as const; + const t4 = [1, , 2] as const; + const t5 = [1, , , 2] as const; + } + + // Example from #13195 + + type Props = { + foo: string; + bar: string + } + + type InputProps = { + foo?: string; + bar: string; + } + + const defaultProps: Pick = { foo: 'foo' }; + const inputProps: InputProps = { foo: undefined, bar: 'bar' }; + ~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 tests/cases/compiler/strictOptionalProperties1.ts:94:5: The expected type comes from property 'foo' which is declared here on type 'InputProps' + const completeProps: Props = { ...defaultProps, ...inputProps }; + + // Example from #13195 + + const t1: [number, string?, boolean?] = [1]; + const t2: [number, string?, boolean?] = [1, undefined]; + ~~~~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + const t3: [number, string?, boolean?] = [1, "string", undefined]; + ~~~~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'boolean'. + const t4: [number, string?, boolean?] = [1, undefined, undefined]; + ~~~~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + ~~~~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'boolean'. + + // Example from #13195 + + const x: { foo?: number } = { foo: undefined }; + ~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. +!!! related TS6500 tests/cases/compiler/strictOptionalProperties1.ts:111:12: The expected type comes from property 'foo' which is declared here on type '{ foo?: number; }' + const y: { foo: number } = { foo: 123, ...x }; + + // Index signatures and strict optional properties + + interface Test { + [key: string]: string; + foo?: string; // Should be ok + bar?: string | undefined; // Error + ~~~ +!!! error TS2411: Property 'bar' of type 'string | undefined' is not assignable to string index type 'string'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/strictOptionalProperties1.js b/tests/baselines/reference/strictOptionalProperties1.js new file mode 100644 index 0000000000000..028e43b9ca614 --- /dev/null +++ b/tests/baselines/reference/strictOptionalProperties1.js @@ -0,0 +1,270 @@ +//// [strictOptionalProperties1.ts] +function f1(obj: { a?: string, b?: string | undefined }) { + let a = obj.a; // string | undefined + let b = obj.b; // string | undefined + obj.a = 'hello'; + obj.b = 'hello'; + obj.a = undefined; // Error + obj.b = undefined; +} + +function f2(obj: { a?: string, b?: string | undefined }) { + obj = obj; + obj.a = obj.a; // Error + obj.b = obj.b; + if ('a' in obj) { + obj.a; + obj.a = obj.a; + } + else { + obj.a; + obj.a = obj.a; // Error + } + if (obj.hasOwnProperty('a')) { + obj.a; + obj.a = obj.a; + } + else { + obj.a; + obj.a = obj.a; // Error + } + if ('b' in obj) { + obj.b; + obj.b = obj.b; + } + else { + obj.b; + obj.b = obj.b; + } + if (obj.hasOwnProperty('b')) { + obj.b; + obj.b = obj.b; + } + else { + obj.b; + obj.b = obj.b; + } +} + +function f3(obj: Partial<{ a: string, b: string | undefined }>) { + let a = obj.a; // string | undefined + let b = obj.b; // string | undefined + obj.a = 'hello'; + obj.b = 'hello'; + obj.a = undefined; // Error + obj.b = undefined; +} + +function f4(t: [string?]) { + let x = t[0]; // string | undefined + t[0] = 'hello'; + t[0] = undefined; // Error +} + +function f4a(t1: [number, string?], t2: [number, string?, string?]) { + t1 = t2; // Wasn't an error, but should be +} + +function f5(t: [number, string?, boolean?]) { + t = [42]; + t = [42, 'abc']; + t = [42, 'abc', true]; + t = [42, ,]; + t = [42, , ,]; + t = [42, , , ,]; // Error + t = [, , true]; // Error + t = [42, undefined, true]; // Error +} + +function f6() { + const t1 = [1, 2] as const; + const t2 = [1, 2, ,] as const; + const t3 = [1, 2, , ,] as const; + const t4 = [1, , 2] as const; + const t5 = [1, , , 2] as const; +} + +// Example from #13195 + +type Props = { + foo: string; + bar: string +} + +type InputProps = { + foo?: string; + bar: string; +} + +const defaultProps: Pick = { foo: 'foo' }; +const inputProps: InputProps = { foo: undefined, bar: 'bar' }; +const completeProps: Props = { ...defaultProps, ...inputProps }; + +// Example from #13195 + +const t1: [number, string?, boolean?] = [1]; +const t2: [number, string?, boolean?] = [1, undefined]; +const t3: [number, string?, boolean?] = [1, "string", undefined]; +const t4: [number, string?, boolean?] = [1, undefined, undefined]; + +// Example from #13195 + +const x: { foo?: number } = { foo: undefined }; +const y: { foo: number } = { foo: 123, ...x }; + +// Index signatures and strict optional properties + +interface Test { + [key: string]: string; + foo?: string; // Should be ok + bar?: string | undefined; // Error +} + + +//// [strictOptionalProperties1.js] +"use strict"; +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +function f1(obj) { + var a = obj.a; // string | undefined + var b = obj.b; // string | undefined + obj.a = 'hello'; + obj.b = 'hello'; + obj.a = undefined; // Error + obj.b = undefined; +} +function f2(obj) { + obj = obj; + obj.a = obj.a; // Error + obj.b = obj.b; + if ('a' in obj) { + obj.a; + obj.a = obj.a; + } + else { + obj.a; + obj.a = obj.a; // Error + } + if (obj.hasOwnProperty('a')) { + obj.a; + obj.a = obj.a; + } + else { + obj.a; + obj.a = obj.a; // Error + } + if ('b' in obj) { + obj.b; + obj.b = obj.b; + } + else { + obj.b; + obj.b = obj.b; + } + if (obj.hasOwnProperty('b')) { + obj.b; + obj.b = obj.b; + } + else { + obj.b; + obj.b = obj.b; + } +} +function f3(obj) { + var a = obj.a; // string | undefined + var b = obj.b; // string | undefined + obj.a = 'hello'; + obj.b = 'hello'; + obj.a = undefined; // Error + obj.b = undefined; +} +function f4(t) { + var x = t[0]; // string | undefined + t[0] = 'hello'; + t[0] = undefined; // Error +} +function f4a(t1, t2) { + t1 = t2; // Wasn't an error, but should be +} +function f5(t) { + t = [42]; + t = [42, 'abc']; + t = [42, 'abc', true]; + t = [42, ,]; + t = [42, , ,]; + t = [42, , , ,]; // Error + t = [, , true]; // Error + t = [42, undefined, true]; // Error +} +function f6() { + var t1 = [1, 2]; + var t2 = [1, 2, ,]; + var t3 = [1, 2, , ,]; + var t4 = [1, , 2]; + var t5 = [1, , , 2]; +} +var defaultProps = { foo: 'foo' }; +var inputProps = { foo: undefined, bar: 'bar' }; +var completeProps = __assign(__assign({}, defaultProps), inputProps); +// Example from #13195 +var t1 = [1]; +var t2 = [1, undefined]; +var t3 = [1, "string", undefined]; +var t4 = [1, undefined, undefined]; +// Example from #13195 +var x = { foo: undefined }; +var y = __assign({ foo: 123 }, x); + + +//// [strictOptionalProperties1.d.ts] +declare function f1(obj: { + a?: string; + b?: string | undefined; +}): void; +declare function f2(obj: { + a?: string; + b?: string | undefined; +}): void; +declare function f3(obj: Partial<{ + a: string; + b: string | undefined; +}>): void; +declare function f4(t: [string?]): void; +declare function f4a(t1: [number, string?], t2: [number, string?, string?]): void; +declare function f5(t: [number, string?, boolean?]): void; +declare function f6(): void; +declare type Props = { + foo: string; + bar: string; +}; +declare type InputProps = { + foo?: string; + bar: string; +}; +declare const defaultProps: Pick; +declare const inputProps: InputProps; +declare const completeProps: Props; +declare const t1: [number, string?, boolean?]; +declare const t2: [number, string?, boolean?]; +declare const t3: [number, string?, boolean?]; +declare const t4: [number, string?, boolean?]; +declare const x: { + foo?: number; +}; +declare const y: { + foo: number; +}; +interface Test { + [key: string]: string; + foo?: string; + bar?: string | undefined; +} diff --git a/tests/baselines/reference/strictOptionalProperties1.symbols b/tests/baselines/reference/strictOptionalProperties1.symbols new file mode 100644 index 0000000000000..33caabc10f344 --- /dev/null +++ b/tests/baselines/reference/strictOptionalProperties1.symbols @@ -0,0 +1,402 @@ +=== tests/cases/compiler/strictOptionalProperties1.ts === +function f1(obj: { a?: string, b?: string | undefined }) { +>f1 : Symbol(f1, Decl(strictOptionalProperties1.ts, 0, 0)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 0, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 0, 18)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 0, 30)) + + let a = obj.a; // string | undefined +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 1, 7)) +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 0, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 0, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 0, 18)) + + let b = obj.b; // string | undefined +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 2, 7)) +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 0, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 0, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 0, 30)) + + obj.a = 'hello'; +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 0, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 0, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 0, 18)) + + obj.b = 'hello'; +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 0, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 0, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 0, 30)) + + obj.a = undefined; // Error +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 0, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 0, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 0, 18)) +>undefined : Symbol(undefined) + + obj.b = undefined; +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 0, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 0, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 0, 30)) +>undefined : Symbol(undefined) +} + +function f2(obj: { a?: string, b?: string | undefined }) { +>f2 : Symbol(f2, Decl(strictOptionalProperties1.ts, 7, 1)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) + + obj = obj; +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) + + obj.a = obj.a; // Error +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) + + obj.b = obj.b; +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) + + if ('a' in obj) { +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) + + obj.a; +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) + + obj.a = obj.a; +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) + } + else { + obj.a; +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) + + obj.a = obj.a; // Error +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) + } + if (obj.hasOwnProperty('a')) { +>obj.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) + + obj.a; +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) + + obj.a = obj.a; +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) + } + else { + obj.a; +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) + + obj.a = obj.a; // Error +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 9, 18)) + } + if ('b' in obj) { +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) + + obj.b; +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) + + obj.b = obj.b; +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) + } + else { + obj.b; +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) + + obj.b = obj.b; +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) + } + if (obj.hasOwnProperty('b')) { +>obj.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) + + obj.b; +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) + + obj.b = obj.b; +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) + } + else { + obj.b; +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) + + obj.b = obj.b; +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 9, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 9, 30)) + } +} + +function f3(obj: Partial<{ a: string, b: string | undefined }>) { +>f3 : Symbol(f3, Decl(strictOptionalProperties1.ts, 45, 1)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 47, 12)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 47, 26)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 47, 37)) + + let a = obj.a; // string | undefined +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 48, 7)) +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 47, 26)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 47, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 47, 26)) + + let b = obj.b; // string | undefined +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 49, 7)) +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 47, 37)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 47, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 47, 37)) + + obj.a = 'hello'; +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 47, 26)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 47, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 47, 26)) + + obj.b = 'hello'; +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 47, 37)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 47, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 47, 37)) + + obj.a = undefined; // Error +>obj.a : Symbol(a, Decl(strictOptionalProperties1.ts, 47, 26)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 47, 12)) +>a : Symbol(a, Decl(strictOptionalProperties1.ts, 47, 26)) +>undefined : Symbol(undefined) + + obj.b = undefined; +>obj.b : Symbol(b, Decl(strictOptionalProperties1.ts, 47, 37)) +>obj : Symbol(obj, Decl(strictOptionalProperties1.ts, 47, 12)) +>b : Symbol(b, Decl(strictOptionalProperties1.ts, 47, 37)) +>undefined : Symbol(undefined) +} + +function f4(t: [string?]) { +>f4 : Symbol(f4, Decl(strictOptionalProperties1.ts, 54, 1)) +>t : Symbol(t, Decl(strictOptionalProperties1.ts, 56, 12)) + + let x = t[0]; // string | undefined +>x : Symbol(x, Decl(strictOptionalProperties1.ts, 57, 7)) +>t : Symbol(t, Decl(strictOptionalProperties1.ts, 56, 12)) +>0 : Symbol(0) + + t[0] = 'hello'; +>t : Symbol(t, Decl(strictOptionalProperties1.ts, 56, 12)) +>0 : Symbol(0) + + t[0] = undefined; // Error +>t : Symbol(t, Decl(strictOptionalProperties1.ts, 56, 12)) +>0 : Symbol(0) +>undefined : Symbol(undefined) +} + +function f4a(t1: [number, string?], t2: [number, string?, string?]) { +>f4a : Symbol(f4a, Decl(strictOptionalProperties1.ts, 60, 1)) +>t1 : Symbol(t1, Decl(strictOptionalProperties1.ts, 62, 13)) +>t2 : Symbol(t2, Decl(strictOptionalProperties1.ts, 62, 35)) + + t1 = t2; // Wasn't an error, but should be +>t1 : Symbol(t1, Decl(strictOptionalProperties1.ts, 62, 13)) +>t2 : Symbol(t2, Decl(strictOptionalProperties1.ts, 62, 35)) +} + +function f5(t: [number, string?, boolean?]) { +>f5 : Symbol(f5, Decl(strictOptionalProperties1.ts, 64, 1)) +>t : Symbol(t, Decl(strictOptionalProperties1.ts, 66, 12)) + + t = [42]; +>t : Symbol(t, Decl(strictOptionalProperties1.ts, 66, 12)) + + t = [42, 'abc']; +>t : Symbol(t, Decl(strictOptionalProperties1.ts, 66, 12)) + + t = [42, 'abc', true]; +>t : Symbol(t, Decl(strictOptionalProperties1.ts, 66, 12)) + + t = [42, ,]; +>t : Symbol(t, Decl(strictOptionalProperties1.ts, 66, 12)) + + t = [42, , ,]; +>t : Symbol(t, Decl(strictOptionalProperties1.ts, 66, 12)) + + t = [42, , , ,]; // Error +>t : Symbol(t, Decl(strictOptionalProperties1.ts, 66, 12)) + + t = [, , true]; // Error +>t : Symbol(t, Decl(strictOptionalProperties1.ts, 66, 12)) + + t = [42, undefined, true]; // Error +>t : Symbol(t, Decl(strictOptionalProperties1.ts, 66, 12)) +>undefined : Symbol(undefined) +} + +function f6() { +>f6 : Symbol(f6, Decl(strictOptionalProperties1.ts, 75, 1)) + + const t1 = [1, 2] as const; +>t1 : Symbol(t1, Decl(strictOptionalProperties1.ts, 78, 9)) + + const t2 = [1, 2, ,] as const; +>t2 : Symbol(t2, Decl(strictOptionalProperties1.ts, 79, 9)) + + const t3 = [1, 2, , ,] as const; +>t3 : Symbol(t3, Decl(strictOptionalProperties1.ts, 80, 9)) + + const t4 = [1, , 2] as const; +>t4 : Symbol(t4, Decl(strictOptionalProperties1.ts, 81, 9)) + + const t5 = [1, , , 2] as const; +>t5 : Symbol(t5, Decl(strictOptionalProperties1.ts, 82, 9)) +} + +// Example from #13195 + +type Props = { +>Props : Symbol(Props, Decl(strictOptionalProperties1.ts, 83, 1)) + + foo: string; +>foo : Symbol(foo, Decl(strictOptionalProperties1.ts, 87, 14)) + + bar: string +>bar : Symbol(bar, Decl(strictOptionalProperties1.ts, 88, 16)) +} + +type InputProps = { +>InputProps : Symbol(InputProps, Decl(strictOptionalProperties1.ts, 90, 1)) + + foo?: string; +>foo : Symbol(foo, Decl(strictOptionalProperties1.ts, 92, 19)) + + bar: string; +>bar : Symbol(bar, Decl(strictOptionalProperties1.ts, 93, 17)) +} + +const defaultProps: Pick = { foo: 'foo' }; +>defaultProps : Symbol(defaultProps, Decl(strictOptionalProperties1.ts, 97, 5)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>Props : Symbol(Props, Decl(strictOptionalProperties1.ts, 83, 1)) +>foo : Symbol(foo, Decl(strictOptionalProperties1.ts, 97, 42)) + +const inputProps: InputProps = { foo: undefined, bar: 'bar' }; +>inputProps : Symbol(inputProps, Decl(strictOptionalProperties1.ts, 98, 5)) +>InputProps : Symbol(InputProps, Decl(strictOptionalProperties1.ts, 90, 1)) +>foo : Symbol(foo, Decl(strictOptionalProperties1.ts, 98, 32)) +>undefined : Symbol(undefined) +>bar : Symbol(bar, Decl(strictOptionalProperties1.ts, 98, 48)) + +const completeProps: Props = { ...defaultProps, ...inputProps }; +>completeProps : Symbol(completeProps, Decl(strictOptionalProperties1.ts, 99, 5)) +>Props : Symbol(Props, Decl(strictOptionalProperties1.ts, 83, 1)) +>defaultProps : Symbol(defaultProps, Decl(strictOptionalProperties1.ts, 97, 5)) +>inputProps : Symbol(inputProps, Decl(strictOptionalProperties1.ts, 98, 5)) + +// Example from #13195 + +const t1: [number, string?, boolean?] = [1]; +>t1 : Symbol(t1, Decl(strictOptionalProperties1.ts, 103, 5)) + +const t2: [number, string?, boolean?] = [1, undefined]; +>t2 : Symbol(t2, Decl(strictOptionalProperties1.ts, 104, 5)) +>undefined : Symbol(undefined) + +const t3: [number, string?, boolean?] = [1, "string", undefined]; +>t3 : Symbol(t3, Decl(strictOptionalProperties1.ts, 105, 5)) +>undefined : Symbol(undefined) + +const t4: [number, string?, boolean?] = [1, undefined, undefined]; +>t4 : Symbol(t4, Decl(strictOptionalProperties1.ts, 106, 5)) +>undefined : Symbol(undefined) +>undefined : Symbol(undefined) + +// Example from #13195 + +const x: { foo?: number } = { foo: undefined }; +>x : Symbol(x, Decl(strictOptionalProperties1.ts, 110, 5)) +>foo : Symbol(foo, Decl(strictOptionalProperties1.ts, 110, 10)) +>foo : Symbol(foo, Decl(strictOptionalProperties1.ts, 110, 29)) +>undefined : Symbol(undefined) + +const y: { foo: number } = { foo: 123, ...x }; +>y : Symbol(y, Decl(strictOptionalProperties1.ts, 111, 5)) +>foo : Symbol(foo, Decl(strictOptionalProperties1.ts, 111, 10)) +>foo : Symbol(foo, Decl(strictOptionalProperties1.ts, 111, 28)) +>x : Symbol(x, Decl(strictOptionalProperties1.ts, 110, 5)) + +// Index signatures and strict optional properties + +interface Test { +>Test : Symbol(Test, Decl(strictOptionalProperties1.ts, 111, 46)) + + [key: string]: string; +>key : Symbol(key, Decl(strictOptionalProperties1.ts, 116, 5)) + + foo?: string; // Should be ok +>foo : Symbol(Test.foo, Decl(strictOptionalProperties1.ts, 116, 26)) + + bar?: string | undefined; // Error +>bar : Symbol(Test.bar, Decl(strictOptionalProperties1.ts, 117, 17)) +} + diff --git a/tests/baselines/reference/strictOptionalProperties1.types b/tests/baselines/reference/strictOptionalProperties1.types new file mode 100644 index 0000000000000..fd208b335d905 --- /dev/null +++ b/tests/baselines/reference/strictOptionalProperties1.types @@ -0,0 +1,512 @@ +=== tests/cases/compiler/strictOptionalProperties1.ts === +function f1(obj: { a?: string, b?: string | undefined }) { +>f1 : (obj: { a?: string; b?: string | undefined; }) => void +>obj : { a?: string; b?: string | undefined; } +>a : string | undefined +>b : string | undefined + + let a = obj.a; // string | undefined +>a : string | undefined +>obj.a : string | undefined +>obj : { a?: string; b?: string | undefined; } +>a : string | undefined + + let b = obj.b; // string | undefined +>b : string | undefined +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined + + obj.a = 'hello'; +>obj.a = 'hello' : "hello" +>obj.a : string +>obj : { a?: string; b?: string | undefined; } +>a : string +>'hello' : "hello" + + obj.b = 'hello'; +>obj.b = 'hello' : "hello" +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined +>'hello' : "hello" + + obj.a = undefined; // Error +>obj.a = undefined : undefined +>obj.a : string +>obj : { a?: string; b?: string | undefined; } +>a : string +>undefined : undefined + + obj.b = undefined; +>obj.b = undefined : undefined +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined +>undefined : undefined +} + +function f2(obj: { a?: string, b?: string | undefined }) { +>f2 : (obj: { a?: string; b?: string | undefined;}) => void +>obj : { a?: string; b?: string | undefined; } +>a : string | undefined +>b : string | undefined + + obj = obj; +>obj = obj : { a?: string; b?: string | undefined; } +>obj : { a?: string; b?: string | undefined; } +>obj : { a?: string; b?: string | undefined; } + + obj.a = obj.a; // Error +>obj.a = obj.a : string | undefined +>obj.a : string +>obj : { a?: string; b?: string | undefined; } +>a : string +>obj.a : string | undefined +>obj : { a?: string; b?: string | undefined; } +>a : string | undefined + + obj.b = obj.b; +>obj.b = obj.b : string | undefined +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined + + if ('a' in obj) { +>'a' in obj : boolean +>'a' : "a" +>obj : { a?: string; b?: string | undefined; } + + obj.a; +>obj.a : string +>obj : { a?: string; b?: string | undefined; } +>a : string + + obj.a = obj.a; +>obj.a = obj.a : string +>obj.a : string +>obj : { a?: string; b?: string | undefined; } +>a : string +>obj.a : string +>obj : { a?: string; b?: string | undefined; } +>a : string + } + else { + obj.a; +>obj.a : undefined +>obj : { a?: string; b?: string | undefined; } +>a : undefined + + obj.a = obj.a; // Error +>obj.a = obj.a : undefined +>obj.a : string +>obj : { a?: string; b?: string | undefined; } +>a : string +>obj.a : undefined +>obj : { a?: string; b?: string | undefined; } +>a : undefined + } + if (obj.hasOwnProperty('a')) { +>obj.hasOwnProperty('a') : boolean +>obj.hasOwnProperty : (v: PropertyKey) => boolean +>obj : { a?: string; b?: string | undefined; } +>hasOwnProperty : (v: PropertyKey) => boolean +>'a' : "a" + + obj.a; +>obj.a : string +>obj : { a?: string; b?: string | undefined; } +>a : string + + obj.a = obj.a; +>obj.a = obj.a : string +>obj.a : string +>obj : { a?: string; b?: string | undefined; } +>a : string +>obj.a : string +>obj : { a?: string; b?: string | undefined; } +>a : string + } + else { + obj.a; +>obj.a : undefined +>obj : { a?: string; b?: string | undefined; } +>a : undefined + + obj.a = obj.a; // Error +>obj.a = obj.a : undefined +>obj.a : string +>obj : { a?: string; b?: string | undefined; } +>a : string +>obj.a : undefined +>obj : { a?: string; b?: string | undefined; } +>a : undefined + } + if ('b' in obj) { +>'b' in obj : boolean +>'b' : "b" +>obj : { a?: string; b?: string | undefined; } + + obj.b; +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined + + obj.b = obj.b; +>obj.b = obj.b : string | undefined +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined + } + else { + obj.b; +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined + + obj.b = obj.b; +>obj.b = obj.b : string | undefined +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined + } + if (obj.hasOwnProperty('b')) { +>obj.hasOwnProperty('b') : boolean +>obj.hasOwnProperty : (v: PropertyKey) => boolean +>obj : { a?: string; b?: string | undefined; } +>hasOwnProperty : (v: PropertyKey) => boolean +>'b' : "b" + + obj.b; +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined + + obj.b = obj.b; +>obj.b = obj.b : string | undefined +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined + } + else { + obj.b; +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined + + obj.b = obj.b; +>obj.b = obj.b : string | undefined +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined +>obj.b : string | undefined +>obj : { a?: string; b?: string | undefined; } +>b : string | undefined + } +} + +function f3(obj: Partial<{ a: string, b: string | undefined }>) { +>f3 : (obj: Partial<{ a: string; b: string | undefined; }>) => void +>obj : Partial<{ a: string; b: string | undefined; }> +>a : string +>b : string | undefined + + let a = obj.a; // string | undefined +>a : string | undefined +>obj.a : string | undefined +>obj : Partial<{ a: string; b: string | undefined; }> +>a : string | undefined + + let b = obj.b; // string | undefined +>b : string | undefined +>obj.b : string | undefined +>obj : Partial<{ a: string; b: string | undefined; }> +>b : string | undefined + + obj.a = 'hello'; +>obj.a = 'hello' : "hello" +>obj.a : string +>obj : Partial<{ a: string; b: string | undefined; }> +>a : string +>'hello' : "hello" + + obj.b = 'hello'; +>obj.b = 'hello' : "hello" +>obj.b : string | undefined +>obj : Partial<{ a: string; b: string | undefined; }> +>b : string | undefined +>'hello' : "hello" + + obj.a = undefined; // Error +>obj.a = undefined : undefined +>obj.a : string +>obj : Partial<{ a: string; b: string | undefined; }> +>a : string +>undefined : undefined + + obj.b = undefined; +>obj.b = undefined : undefined +>obj.b : string | undefined +>obj : Partial<{ a: string; b: string | undefined; }> +>b : string | undefined +>undefined : undefined +} + +function f4(t: [string?]) { +>f4 : (t: [string?]) => void +>t : [string?] + + let x = t[0]; // string | undefined +>x : string | undefined +>t[0] : string | undefined +>t : [string?] +>0 : 0 + + t[0] = 'hello'; +>t[0] = 'hello' : "hello" +>t[0] : string +>t : [string?] +>0 : 0 +>'hello' : "hello" + + t[0] = undefined; // Error +>t[0] = undefined : undefined +>t[0] : string +>t : [string?] +>0 : 0 +>undefined : undefined +} + +function f4a(t1: [number, string?], t2: [number, string?, string?]) { +>f4a : (t1: [number, string?], t2: [number, string?, string?]) => void +>t1 : [number, string?] +>t2 : [number, string?, string?] + + t1 = t2; // Wasn't an error, but should be +>t1 = t2 : [number, string?, string?] +>t1 : [number, string?] +>t2 : [number, string?, string?] +} + +function f5(t: [number, string?, boolean?]) { +>f5 : (t: [number, string?, boolean?]) => void +>t : [number, string?, boolean?] + + t = [42]; +>t = [42] : [number] +>t : [number, string?, boolean?] +>[42] : [number] +>42 : 42 + + t = [42, 'abc']; +>t = [42, 'abc'] : [number, string] +>t : [number, string?, boolean?] +>[42, 'abc'] : [number, string] +>42 : 42 +>'abc' : "abc" + + t = [42, 'abc', true]; +>t = [42, 'abc', true] : [number, string, true] +>t : [number, string?, boolean?] +>[42, 'abc', true] : [number, string, true] +>42 : 42 +>'abc' : "abc" +>true : true + + t = [42, ,]; +>t = [42, ,] : [number, never?] +>t : [number, string?, boolean?] +>[42, ,] : [number, never?] +>42 : 42 +> : undefined + + t = [42, , ,]; +>t = [42, , ,] : [number, never?, never?] +>t : [number, string?, boolean?] +>[42, , ,] : [number, never?, never?] +>42 : 42 +> : undefined +> : undefined + + t = [42, , , ,]; // Error +>t = [42, , , ,] : [number, never?, never?, never?] +>t : [number, string?, boolean?] +>[42, , , ,] : [number, never?, never?, never?] +>42 : 42 +> : undefined +> : undefined +> : undefined + + t = [, , true]; // Error +>t = [, , true] : [never?, never?, true?] +>t : [number, string?, boolean?] +>[, , true] : [never?, never?, true?] +> : undefined +> : undefined +>true : true + + t = [42, undefined, true]; // Error +>t = [42, undefined, true] : [number, undefined, true] +>t : [number, string?, boolean?] +>[42, undefined, true] : [number, undefined, true] +>42 : 42 +>undefined : undefined +>true : true +} + +function f6() { +>f6 : () => void + + const t1 = [1, 2] as const; +>t1 : readonly [1, 2] +>[1, 2] as const : readonly [1, 2] +>[1, 2] : readonly [1, 2] +>1 : 1 +>2 : 2 + + const t2 = [1, 2, ,] as const; +>t2 : readonly [1, 2, never?] +>[1, 2, ,] as const : readonly [1, 2, never?] +>[1, 2, ,] : readonly [1, 2, never?] +>1 : 1 +>2 : 2 +> : undefined + + const t3 = [1, 2, , ,] as const; +>t3 : readonly [1, 2, never?, never?] +>[1, 2, , ,] as const : readonly [1, 2, never?, never?] +>[1, 2, , ,] : readonly [1, 2, never?, never?] +>1 : 1 +>2 : 2 +> : undefined +> : undefined + + const t4 = [1, , 2] as const; +>t4 : readonly [1, never?, 2?] +>[1, , 2] as const : readonly [1, never?, 2?] +>[1, , 2] : readonly [1, never?, 2?] +>1 : 1 +> : undefined +>2 : 2 + + const t5 = [1, , , 2] as const; +>t5 : readonly [1, never?, never?, 2?] +>[1, , , 2] as const : readonly [1, never?, never?, 2?] +>[1, , , 2] : readonly [1, never?, never?, 2?] +>1 : 1 +> : undefined +> : undefined +>2 : 2 +} + +// Example from #13195 + +type Props = { +>Props : Props + + foo: string; +>foo : string + + bar: string +>bar : string +} + +type InputProps = { +>InputProps : InputProps + + foo?: string; +>foo : string | undefined + + bar: string; +>bar : string +} + +const defaultProps: Pick = { foo: 'foo' }; +>defaultProps : Pick +>{ foo: 'foo' } : { foo: string; } +>foo : string +>'foo' : "foo" + +const inputProps: InputProps = { foo: undefined, bar: 'bar' }; +>inputProps : InputProps +>{ foo: undefined, bar: 'bar' } : { foo: undefined; bar: string; } +>foo : undefined +>undefined : undefined +>bar : string +>'bar' : "bar" + +const completeProps: Props = { ...defaultProps, ...inputProps }; +>completeProps : Props +>{ ...defaultProps, ...inputProps } : { foo: string; bar: string; } +>defaultProps : Pick +>inputProps : InputProps + +// Example from #13195 + +const t1: [number, string?, boolean?] = [1]; +>t1 : [number, string?, boolean?] +>[1] : [number] +>1 : 1 + +const t2: [number, string?, boolean?] = [1, undefined]; +>t2 : [number, string?, boolean?] +>[1, undefined] : [number, undefined] +>1 : 1 +>undefined : undefined + +const t3: [number, string?, boolean?] = [1, "string", undefined]; +>t3 : [number, string?, boolean?] +>[1, "string", undefined] : [number, string, undefined] +>1 : 1 +>"string" : "string" +>undefined : undefined + +const t4: [number, string?, boolean?] = [1, undefined, undefined]; +>t4 : [number, string?, boolean?] +>[1, undefined, undefined] : [number, undefined, undefined] +>1 : 1 +>undefined : undefined +>undefined : undefined + +// Example from #13195 + +const x: { foo?: number } = { foo: undefined }; +>x : { foo?: number; } +>foo : number | undefined +>{ foo: undefined } : { foo: undefined; } +>foo : undefined +>undefined : undefined + +const y: { foo: number } = { foo: 123, ...x }; +>y : { foo: number; } +>foo : number +>{ foo: 123, ...x } : { foo: number; } +>foo : number +>123 : 123 +>x : { foo?: number; } + +// Index signatures and strict optional properties + +interface Test { + [key: string]: string; +>key : string + + foo?: string; // Should be ok +>foo : string | undefined + + bar?: string | undefined; // Error +>bar : string | undefined +} + diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index 194d0d139323d..35ac1ca34a005 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -31,6 +31,7 @@ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json index 6cd483e76a9f0..86cba7228c0d6 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json @@ -31,6 +31,7 @@ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index d10611ebdae17..266c6b2be47bf 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -31,6 +31,7 @@ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index 485a029ae8329..1e44f00df8d0c 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -31,6 +31,7 @@ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index 66028174a9ea6..ad96c0e4f2af9 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -31,6 +31,7 @@ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index d926a958770fe..252621612e447 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -31,6 +31,7 @@ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index 194d0d139323d..35ac1ca34a005 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -31,6 +31,7 @@ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index 9c4a96d98d35c..a262bbec98a68 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -31,6 +31,7 @@ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index dd5852675808c..3172471f565e2 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -31,6 +31,7 @@ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsc/runWithoutArgs/initial-build/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js b/tests/baselines/reference/tsc/runWithoutArgs/initial-build/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js index 362d9209ea89e..db5d005ad3d51 100644 --- a/tests/baselines/reference/tsc/runWithoutArgs/initial-build/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js +++ b/tests/baselines/reference/tsc/runWithoutArgs/initial-build/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js @@ -42,6 +42,7 @@ Options: --strictFunctionTypes Enable strict checking of function types. --strictBindCallApply Enable strict 'bind', 'call', and 'apply' methods on functions. --strictPropertyInitialization Enable strict checking of property initialization in classes. + --strictOptionalProperties Enable strict checking of optional properties. --noImplicitThis Raise error on 'this' expressions with an implied 'any' type. --alwaysStrict Parse in strict mode and emit "use strict" for each source file. --noUnusedLocals Report errors on unused locals. diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js index 16b925d5936d4..c1434a3272f3b 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js @@ -52,6 +52,7 @@ interface Array { length: number; [n: number]: T; } // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js index 7ce20f4eb951f..3ee57a0b601b2 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js @@ -52,6 +52,7 @@ interface Array { length: number; [n: number]: T; } // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js index f35e860335bb8..efc757cd359e8 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js @@ -52,6 +52,7 @@ interface Array { length: number; [n: number]: T; } // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js index 8f6c7e53cc61b..42e6b1b7b3ed7 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js @@ -52,6 +52,7 @@ interface Array { length: number; [n: number]: T; } // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified-with-declaration-enabled.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified-with-declaration-enabled.js index 0bc0a489d1891..983f3d02c604c 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified-with-declaration-enabled.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified-with-declaration-enabled.js @@ -52,6 +52,7 @@ interface Array { length: number; [n: number]: T; } // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js index 79c6b55b1f1e0..e1aa9b0741c8e 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js @@ -52,6 +52,7 @@ interface Array { length: number; [n: number]: T; } // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "strictOptionalProperties": true, /* Enable strict checking of optional properties. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ diff --git a/tests/baselines/reference/tsxInvokeComponentType.types b/tests/baselines/reference/tsxInvokeComponentType.types index a8cad986828b1..fc20c0caf527b 100644 --- a/tests/baselines/reference/tsxInvokeComponentType.types +++ b/tests/baselines/reference/tsxInvokeComponentType.types @@ -20,12 +20,12 @@ const good = ; >someKey : string declare const Elem2: ComponentType<{ opt?: number }>; ->Elem2 : React.ComponentType<{ opt?: number | undefined; }> +>Elem2 : React.ComponentType<{ opt?: number; }> >opt : number | undefined const alsoOk = text; >alsoOk : JSX.Element >text : JSX.Element ->Elem2 : React.ComponentType<{ opt?: number | undefined; }> ->Elem2 : React.ComponentType<{ opt?: number | undefined; }> +>Elem2 : React.ComponentType<{ opt?: number; }> +>Elem2 : React.ComponentType<{ opt?: number; }> diff --git a/tests/baselines/reference/tsxLibraryManagedAttributes.errors.txt b/tests/baselines/reference/tsxLibraryManagedAttributes.errors.txt index 75911e6e6c5ca..2f8bd35e62713 100644 --- a/tests/baselines/reference/tsxLibraryManagedAttributes.errors.txt +++ b/tests/baselines/reference/tsxLibraryManagedAttributes.errors.txt @@ -7,7 +7,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(69,26): error TS2322 tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(71,35): error TS2322: Type 'null' is not assignable to type 'ReactNode'. tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(80,38): error TS2322: Type '{ foo: number; bar: string; }' is not assignable to type 'Defaultize<{}, { foo: number; }>'. Property 'bar' does not exist on type 'Defaultize<{}, { foo: number; }>'. -tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(81,29): error TS2322: Type 'string' is not assignable to type 'number | undefined'. +tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(81,29): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(98,12): error TS2322: Type '{ foo: string; }' is not assignable to type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: string; }>'. Type '{ foo: string; }' is missing the following properties from type '{ bar: ReactNode | null | undefined; baz: number; }': bar, baz tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(100,56): error TS2322: Type '{ bar: string; baz: number; bat: string; }' is not assignable to type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: string; }>'. @@ -18,7 +18,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(112,46): error TS232 tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(113,57): error TS2322: Type 'null' is not assignable to type 'ReactNode'. tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(122,58): error TS2322: Type '{ foo: string; bar: string; }' is not assignable to type 'Defaultize'. Property 'bar' does not exist on type 'Defaultize'. -tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS2322: Type 'number' is not assignable to type 'string | undefined'. +tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS2322: Type 'number' is not assignable to type 'string'. ==== tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx (15 errors) ==== @@ -121,7 +121,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232 !!! error TS2322: Property 'bar' does not exist on type 'Defaultize<{}, { foo: number; }>'. const m = ; // error, wrong type ~~~ -!!! error TS2322: Type 'string' is not assignable to type 'number | undefined'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. !!! related TS6500 tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx:75:9: The expected type comes from property 'foo' which is declared here on type 'Defaultize<{}, { foo: number; }>' interface FooProps { @@ -186,7 +186,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232 !!! error TS2322: Property 'bar' does not exist on type 'Defaultize'. const z = ; // error, wrong type ~~~ -!!! error TS2322: Type 'number' is not assignable to type 'string | undefined'. +!!! error TS2322: Type 'number' is not assignable to type 'string'. !!! related TS6500 tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx:117:9: The expected type comes from property 'foo' which is declared here on type 'Defaultize' const aa = ; \ No newline at end of file diff --git a/tests/baselines/reference/typeFromContextualThisType.types b/tests/baselines/reference/typeFromContextualThisType.types index 035ab3eb3b09e..015480578b5b7 100644 --- a/tests/baselines/reference/typeFromContextualThisType.types +++ b/tests/baselines/reference/typeFromContextualThisType.types @@ -20,7 +20,7 @@ const o1 = { /** @type {{ d(): void; e?(n: number): number; f?(n: number): number; g?: number }} */ const o2 = { ->o2 : { d(): void; e?(n: number): number; f?(n: number): number; g?: number | undefined; } +>o2 : { d(): void; e?(n: number): number; f?(n: number): number; g?: number; } >{ d() { this.e = this.f = m => this.g || m; }} : { d(): void; } d() { @@ -29,17 +29,17 @@ const o2 = { this.e = this.f = m => this.g || m; >this.e = this.f = m => this.g || m : (m: number) => number >this.e : ((n: number) => number) | undefined ->this : { d(): void; e?(n: number): number; f?(n: number): number; g?: number | undefined; } +>this : { d(): void; e?(n: number): number; f?(n: number): number; g?: number; } >e : ((n: number) => number) | undefined >this.f = m => this.g || m : (m: number) => number >this.f : ((n: number) => number) | undefined ->this : { d(): void; e?(n: number): number; f?(n: number): number; g?: number | undefined; } +>this : { d(): void; e?(n: number): number; f?(n: number): number; g?: number; } >f : ((n: number) => number) | undefined >m => this.g || m : (m: number) => number >m : number >this.g || m : number >this.g : number | undefined ->this : { d(): void; e?(n: number): number; f?(n: number): number; g?: number | undefined; } +>this : { d(): void; e?(n: number): number; f?(n: number): number; g?: number; } >g : number | undefined >m : number } diff --git a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty.types b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty.types index f88376b118fb0..0d7293ea1efc3 100644 --- a/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty.types +++ b/tests/baselines/reference/typeGuardNarrowsIndexedAccessOfKnownProperty.types @@ -290,15 +290,15 @@ function check(z: Z, c: C) { export function g(pair: [number, string?]): string { >g : (pair: [number, string?]) => string ->pair : [number, (string | undefined)?] +>pair : [number, string?] return pair[1] ? pair[1] : 'nope'; >pair[1] ? pair[1] : 'nope' : string >pair[1] : string | undefined ->pair : [number, (string | undefined)?] +>pair : [number, string?] >1 : 1 >pair[1] : string ->pair : [number, (string | undefined)?] +>pair : [number, string?] >1 : 1 >'nope' : "nope" } diff --git a/tests/baselines/reference/unionExcessPropsWithPartialMember.types b/tests/baselines/reference/unionExcessPropsWithPartialMember.types index 2c3460d977c07..cd6f429b18079 100644 --- a/tests/baselines/reference/unionExcessPropsWithPartialMember.types +++ b/tests/baselines/reference/unionExcessPropsWithPartialMember.types @@ -22,9 +22,9 @@ declare var a: A; >a : A ab = {...a, y: (null as any as string | undefined)}; // Should be allowed, since `y` is missing on `A` ->ab = {...a, y: (null as any as string | undefined)} : { y: string | undefined; unused?: string | undefined; x: string; } +>ab = {...a, y: (null as any as string | undefined)} : { y: string | undefined; unused?: string; x: string; } >ab : A | B ->{...a, y: (null as any as string | undefined)} : { y: string | undefined; unused?: string | undefined; x: string; } +>{...a, y: (null as any as string | undefined)} : { y: string | undefined; unused?: string; x: string; } >a : A >y : string | undefined >(null as any as string | undefined) : string | undefined diff --git a/tests/baselines/reference/unionTypeInference.types b/tests/baselines/reference/unionTypeInference.types index 268d4ed86ebfb..9e54f9e5bd37b 100644 --- a/tests/baselines/reference/unionTypeInference.types +++ b/tests/baselines/reference/unionTypeInference.types @@ -213,26 +213,26 @@ async function fun(deepPromised: DeepPromised) { >deepPromised : DeepPromised for (const value of Object.values(deepPromisedWithIndexer)) { ->value : {} | ({ [containsPromises]?: true | undefined; } & {}) | Promise<{ [containsPromises]?: true | undefined; } & {}> | null | undefined ->Object.values(deepPromisedWithIndexer) : ({} | ({ [containsPromises]?: true | undefined; } & {}) | Promise<{ [containsPromises]?: true | undefined; } & {}> | null | undefined)[] +>value : {} | ({ [containsPromises]?: true; } & {}) | Promise<{ [containsPromises]?: true; } & {}> | null | undefined +>Object.values(deepPromisedWithIndexer) : ({} | ({ [containsPromises]?: true; } & {}) | Promise<{ [containsPromises]?: true; } & {}> | null | undefined)[] >Object.values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } >Object : ObjectConstructor >values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } >deepPromisedWithIndexer : DeepPromised<{ [name: string]: {} | null | undefined; }> const awaitedValue = await value; ->awaitedValue : {} | ({ [containsPromises]?: true | undefined; } & {}) | null | undefined ->await value : {} | ({ [containsPromises]?: true | undefined; } & {}) | null | undefined ->value : {} | ({ [containsPromises]?: true | undefined; } & {}) | Promise<{ [containsPromises]?: true | undefined; } & {}> | null | undefined +>awaitedValue : {} | ({ [containsPromises]?: true; } & {}) | null | undefined +>await value : {} | ({ [containsPromises]?: true; } & {}) | null | undefined +>value : {} | ({ [containsPromises]?: true; } & {}) | Promise<{ [containsPromises]?: true; } & {}> | null | undefined if (awaitedValue) ->awaitedValue : {} | ({ [containsPromises]?: true | undefined; } & {}) | null | undefined +>awaitedValue : {} | ({ [containsPromises]?: true; } & {}) | null | undefined await fun(awaitedValue); >await fun(awaitedValue) : void >fun(awaitedValue) : Promise >fun : (deepPromised: DeepPromised) => Promise ->awaitedValue : {} | ({ [containsPromises]?: true | undefined; } & {}) +>awaitedValue : {} | ({ [containsPromises]?: true; } & {}) } } diff --git a/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.types b/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.types index 62dcc0607ae33..a9f53e30f0bc8 100644 --- a/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.types +++ b/tests/baselines/reference/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.types @@ -21,7 +21,7 @@ export function foo(p: Promise) { p[FOO_SYMBOL] = 3; >p[FOO_SYMBOL] = 3 : 3 ->p[FOO_SYMBOL] : number | undefined +>p[FOO_SYMBOL] : number >p : Promise >FOO_SYMBOL : unique symbol >3 : 3 diff --git a/tests/baselines/reference/variadicTuples1.errors.txt b/tests/baselines/reference/variadicTuples1.errors.txt index 956bd6a922be2..014493e637c3a 100644 --- a/tests/baselines/reference/variadicTuples1.errors.txt +++ b/tests/baselines/reference/variadicTuples1.errors.txt @@ -34,7 +34,7 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(191,5): error TS2322: Typ 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'readonly string[]'. tests/cases/conformance/types/tuple/variadicTuples1.ts(203,5): error TS2322: Type 'string' is not assignable to type 'keyof [1, 2, ...T]'. Type '"2"' is not assignable to type 'number | "0" | keyof T[] | "1"'. -tests/cases/conformance/types/tuple/variadicTuples1.ts(357,26): error TS2322: Type 'string' is not assignable to type 'number | undefined'. +tests/cases/conformance/types/tuple/variadicTuples1.ts(357,26): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/tuple/variadicTuples1.ts(397,7): error TS2322: Type '[false, false]' is not assignable to type '[...number[], boolean]'. Type at position 0 in source is not compatible with type at position 0 in target. Type 'boolean' is not assignable to type 'number'. @@ -454,7 +454,7 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(397,7): error TS2322: Typ let v1 = f20(args); // U let v2 = f20(["foo", "bar"]); // [string] ~~~~~ -!!! error TS2322: Type 'string' is not assignable to type 'number | undefined'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. let v3 = f20(["foo", 42]); // [string] } diff --git a/tests/baselines/reference/variadicTuples1.types b/tests/baselines/reference/variadicTuples1.types index 3bb6d7d6d65c2..01af769fb7683 100644 --- a/tests/baselines/reference/variadicTuples1.types +++ b/tests/baselines/reference/variadicTuples1.types @@ -412,10 +412,10 @@ type TM1 = ArrayifyTM1 : readonly [string[], (number | undefined)[]?, ...Arrayify, ...boolean[][]] type TP1 = Partial<[string, ...T, number]>; // [string?, Partial, number?] ->TP1 : [(string | undefined)?, ...Partial, (number | undefined)?] +>TP1 : [string?, ...Partial, number?] type TP2 = Partial<[string, ...T, ...number[]]>; // [string?, Partial, ...(number | undefined)[]] ->TP2 : [(string | undefined)?, ...Partial, ...(number | undefined)[]] +>TP2 : [string?, ...Partial, ...(number | undefined)[]] // Reverse mapping through mapped type applied to variadic tuple type @@ -897,7 +897,7 @@ type T34 = DropLast<[symbol, ...string[]]>; >T34 : [symbol, ...string[]] type T35 = DropLast<[string?]>; ->T35 : [(string | undefined)?] +>T35 : [string?] type T36 = DropLast; >T36 : string[] @@ -1181,11 +1181,11 @@ curry2(fn10, ['hello'], [42, true]); declare function ft(t1: [...T], t2: [...T, number?]): T; >ft : (t1: [...T], t2: [...T, number?]) => T >t1 : [...T] ->t2 : [...T, (number | undefined)?] +>t2 : [...T, number?] ft([1, 2, 3], [1, 2, 3]); >ft([1, 2, 3], [1, 2, 3]) : [number, number, number] ->ft : (t1: [...T], t2: [...T, (number | undefined)?]) => T +>ft : (t1: [...T], t2: [...T, number?]) => T >[1, 2, 3] : [number, number, number] >1 : 1 >2 : 2 @@ -1197,7 +1197,7 @@ ft([1, 2, 3], [1, 2, 3]); ft([1, 2], [1, 2, 3]); >ft([1, 2], [1, 2, 3]) : [number, number] ->ft : (t1: [...T], t2: [...T, (number | undefined)?]) => T +>ft : (t1: [...T], t2: [...T, number?]) => T >[1, 2] : [number, number] >1 : 1 >2 : 2 @@ -1208,7 +1208,7 @@ ft([1, 2], [1, 2, 3]); ft(['a', 'b'], ['c', 'd']) >ft(['a', 'b'], ['c', 'd']) : [string, string] ->ft : (t1: [...T], t2: [...T, (number | undefined)?]) => T +>ft : (t1: [...T], t2: [...T, number?]) => T >['a', 'b'] : [string, string] >'a' : "a" >'b' : "b" @@ -1218,7 +1218,7 @@ ft(['a', 'b'], ['c', 'd']) ft(['a', 'b'], ['c', 'd', 42]) >ft(['a', 'b'], ['c', 'd', 42]) : [string, string] ->ft : (t1: [...T], t2: [...T, (number | undefined)?]) => T +>ft : (t1: [...T], t2: [...T, number?]) => T >['a', 'b'] : [string, string] >'a' : "a" >'b' : "b" @@ -1257,22 +1257,22 @@ call(...sa, (...x) => 42); declare function f20(args: [...T, number?]): T; >f20 : (args: [...T, number?]) => T ->args : [...T, (number | undefined)?] +>args : [...T, number?] function f21(args: [...U, number?]) { >f21 : (args: [...U, number?]) => void ->args : [...U, (number | undefined)?] +>args : [...U, number?] let v1 = f20(args); // U >v1 : U >f20(args) : U ->f20 : (args: [...T, (number | undefined)?]) => T ->args : [...U, (number | undefined)?] +>f20 : (args: [...T, number?]) => T +>args : [...U, number?] let v2 = f20(["foo", "bar"]); // [string] >v2 : [string] >f20(["foo", "bar"]) : [string] ->f20 : (args: [...T, (number | undefined)?]) => T +>f20 : (args: [...T, number?]) => T >["foo", "bar"] : [string, string] >"foo" : "foo" >"bar" : "bar" @@ -1280,7 +1280,7 @@ function f21(args: [...U, number?]) { let v3 = f20(["foo", 42]); // [string] >v3 : [string] >f20(["foo", 42]) : [string] ->f20 : (args: [...T, (number | undefined)?]) => T +>f20 : (args: [...T, number?]) => T >["foo", 42] : [string, number] >"foo" : "foo" >42 : 42 @@ -1349,16 +1349,16 @@ const b = a.bind("", 1); // Desc<[boolean], object> // Repro from #39607 declare function getUser(id: string, options?: { x?: string }): string; ->getUser : (id: string, options?: { x?: string | undefined; } | undefined) => string +>getUser : (id: string, options?: { x?: string; } | undefined) => string >id : string ->options : { x?: string | undefined; } | undefined +>options : { x?: string; } | undefined >x : string | undefined declare function getOrgUser(id: string, orgId: number, options?: { y?: number, z?: boolean }): void; ->getOrgUser : (id: string, orgId: number, options?: { y?: number | undefined; z?: boolean | undefined; } | undefined) => void +>getOrgUser : (id: string, orgId: number, options?: { y?: number; z?: boolean; } | undefined) => void >id : string >orgId : number ->options : { y?: number | undefined; z?: boolean | undefined; } | undefined +>options : { y?: number; z?: boolean; } | undefined >y : number | undefined >z : boolean | undefined @@ -1380,12 +1380,12 @@ function callApi(method: (...args: [...T, ob callApi(getUser); >callApi(getUser) : (id: string) => string >callApi : (method: (...args: [...T, object]) => U) => (...args_0: T) => U ->getUser : (id: string, options?: { x?: string | undefined; } | undefined) => string +>getUser : (id: string, options?: { x?: string; } | undefined) => string callApi(getOrgUser); >callApi(getOrgUser) : (id: string, orgId: number) => void >callApi : (method: (...args: [...T, object]) => U) => (...args_0: T) => U ->getOrgUser : (id: string, orgId: number, options?: { y?: number | undefined; z?: boolean | undefined; } | undefined) => void +>getOrgUser : (id: string, orgId: number, options?: { y?: number; z?: boolean; } | undefined) => void // Repro from #40235 diff --git a/tests/baselines/reference/variadicTuples2.types b/tests/baselines/reference/variadicTuples2.types index b60c45bc727f6..493d283daa4be 100644 --- a/tests/baselines/reference/variadicTuples2.types +++ b/tests/baselines/reference/variadicTuples2.types @@ -37,7 +37,7 @@ type V23 = Tup3<[number], string[], [boolean?]>; // [number, (string | boolean >V23 : [number, ...(string | boolean | undefined)[]] type V24 = Tup3<[number], [boolean?], string[]>; // [number, boolean?, ...string[]] ->V24 : [number, (boolean | undefined)?, ...string[]] +>V24 : [number, boolean?, ...string[]] type V25 = Tup3; // (string | number | boolean)[] >V25 : (string | number | boolean)[] @@ -46,7 +46,7 @@ type V26 = Tup3; // [...(string | number)[], boo >V26 : [...(string | number)[], boolean] type V27 = Tup3<[number?], [string], [boolean?]>; // [number | undefined, string, boolean?] ->V27 : [number | undefined, string, (boolean | undefined)?] +>V27 : [number | undefined, string, boolean?] type V30 = Tup3; // [...A, ...(string | number)[]] >V30 : [...A, ...(string | number)[]] @@ -58,13 +58,13 @@ type V32 = Tup3; // [...(string | n >V32 : [...(string | number)[], ...A] type V40 = Tup3; // [...A, string?, ...number[]] ->V40 : [...A, (string | undefined)?, ...number[]] +>V40 : [...A, string?, ...number[]] type V41 = Tup3<[string?], A, number[]>; // [string?, ...A, ...number[]] ->V41 : [(string | undefined)?, ...A, ...number[]] +>V41 : [string?, ...A, ...number[]] type V42 = Tup3<[string?], number[], A>; // [string?, ...number[], ...A] ->V42 : [(string | undefined)?, ...number[], ...A] +>V42 : [string?, ...number[], ...A] type V50 = Tup3; // [...A, ...(string | number | undefined)[]] >V50 : [...A, ...(string | number | undefined)[]] diff --git a/tests/cases/compiler/strictOptionalProperties1.ts b/tests/cases/compiler/strictOptionalProperties1.ts new file mode 100644 index 0000000000000..3ebe9773af75a --- /dev/null +++ b/tests/cases/compiler/strictOptionalProperties1.ts @@ -0,0 +1,123 @@ +// @strict: true +// @declaration: true + +function f1(obj: { a?: string, b?: string | undefined }) { + let a = obj.a; // string | undefined + let b = obj.b; // string | undefined + obj.a = 'hello'; + obj.b = 'hello'; + obj.a = undefined; // Error + obj.b = undefined; +} + +function f2(obj: { a?: string, b?: string | undefined }) { + obj = obj; + obj.a = obj.a; // Error + obj.b = obj.b; + if ('a' in obj) { + obj.a; + obj.a = obj.a; + } + else { + obj.a; + obj.a = obj.a; // Error + } + if (obj.hasOwnProperty('a')) { + obj.a; + obj.a = obj.a; + } + else { + obj.a; + obj.a = obj.a; // Error + } + if ('b' in obj) { + obj.b; + obj.b = obj.b; + } + else { + obj.b; + obj.b = obj.b; + } + if (obj.hasOwnProperty('b')) { + obj.b; + obj.b = obj.b; + } + else { + obj.b; + obj.b = obj.b; + } +} + +function f3(obj: Partial<{ a: string, b: string | undefined }>) { + let a = obj.a; // string | undefined + let b = obj.b; // string | undefined + obj.a = 'hello'; + obj.b = 'hello'; + obj.a = undefined; // Error + obj.b = undefined; +} + +function f4(t: [string?]) { + let x = t[0]; // string | undefined + t[0] = 'hello'; + t[0] = undefined; // Error +} + +function f4a(t1: [number, string?], t2: [number, string?, string?]) { + t1 = t2; // Wasn't an error, but should be +} + +function f5(t: [number, string?, boolean?]) { + t = [42]; + t = [42, 'abc']; + t = [42, 'abc', true]; + t = [42, ,]; + t = [42, , ,]; + t = [42, , , ,]; // Error + t = [, , true]; // Error + t = [42, undefined, true]; // Error +} + +function f6() { + const t1 = [1, 2] as const; + const t2 = [1, 2, ,] as const; + const t3 = [1, 2, , ,] as const; + const t4 = [1, , 2] as const; + const t5 = [1, , , 2] as const; +} + +// Example from #13195 + +type Props = { + foo: string; + bar: string +} + +type InputProps = { + foo?: string; + bar: string; +} + +const defaultProps: Pick = { foo: 'foo' }; +const inputProps: InputProps = { foo: undefined, bar: 'bar' }; +const completeProps: Props = { ...defaultProps, ...inputProps }; + +// Example from #13195 + +const t1: [number, string?, boolean?] = [1]; +const t2: [number, string?, boolean?] = [1, undefined]; +const t3: [number, string?, boolean?] = [1, "string", undefined]; +const t4: [number, string?, boolean?] = [1, undefined, undefined]; + +// Example from #13195 + +const x: { foo?: number } = { foo: undefined }; +const y: { foo: number } = { foo: 123, ...x }; + +// Index signatures and strict optional properties + +interface Test { + [key: string]: string; + foo?: string; // Should be ok + bar?: string | undefined; // Error +}