diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index c2bfce10e57d6..a6f5993f6c88d 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -518,7 +518,6 @@ namespace ts { hasExplicitReturn = false; bindChildren(node); // Reset all reachability check related flags on node (for incremental scenarios) - // Reset all emit helper flags on node (for incremental scenarios) node.flags &= ~NodeFlags.ReachabilityAndEmitFlags; if (!(currentFlow.flags & FlowFlags.Unreachable) && containerFlags & ContainerFlags.IsFunctionLike && nodeIsPresent((node).body)) { node.flags |= NodeFlags.HasImplicitReturn; @@ -1950,9 +1949,6 @@ namespace ts { return bindParameter(node); case SyntaxKind.VariableDeclaration: case SyntaxKind.BindingElement: - if ((node as BindingElement).dotDotDotToken && node.parent.kind === SyntaxKind.ObjectBindingPattern) { - emitFlags |= NodeFlags.HasRestAttribute; - } return bindVariableDeclarationOrBindingElement(node); case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: @@ -1980,7 +1976,6 @@ namespace ts { } root = root.parent; } - emitFlags |= hasRest ? NodeFlags.HasRestAttribute : NodeFlags.HasSpreadAttribute; return; case SyntaxKind.CallSignature: @@ -2236,15 +2231,6 @@ namespace ts { } function bindClassLikeDeclaration(node: ClassLikeDeclaration) { - if (!isDeclarationFile(file) && !isInAmbientContext(node)) { - if (getClassExtendsHeritageClauseElement(node) !== undefined) { - emitFlags |= NodeFlags.HasClassExtends; - } - if (nodeIsDecorated(node)) { - emitFlags |= NodeFlags.HasDecorators; - } - } - if (node.kind === SyntaxKind.ClassDeclaration) { bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes); } @@ -2314,12 +2300,6 @@ namespace ts { } function bindParameter(node: ParameterDeclaration) { - if (!isDeclarationFile(file) && - !isInAmbientContext(node) && - nodeIsDecorated(node)) { - emitFlags |= (NodeFlags.HasDecorators | NodeFlags.HasParamDecorators); - } - if (inStrictMode) { // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a // strict mode FunctionLikeDeclaration or FunctionExpression(13.1) @@ -2377,9 +2357,6 @@ namespace ts { if (isAsyncFunctionLike(node)) { emitFlags |= NodeFlags.HasAsyncFunctions; } - if (nodeIsDecorated(node)) { - emitFlags |= NodeFlags.HasDecorators; - } } if (currentFlow && isObjectLiteralOrClassExpressionMethod(node)) { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1ee8a64269fe1..02cde0d4412fc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -38,6 +38,8 @@ namespace ts { // is because diagnostics can be quite expensive, and we want to allow hosts to bail out if // they no longer need the information (for example, if the user started editing again). let cancellationToken: CancellationToken; + let requestedExternalEmitHelpers: ExternalEmitHelpers; + let externalHelpersModule: Symbol; const Symbol = objectAllocator.getSymbolConstructor(); const Type = objectAllocator.getTypeConstructor(); @@ -3054,7 +3056,15 @@ namespace ts { } function getRestType(source: Type, properties: PropertyName[], symbol: Symbol): Type { - Debug.assert(!!(source.flags & TypeFlags.Object), "Rest types only support object types right now."); + source = filterType(source, t => !(t.flags & TypeFlags.Nullable)); + if (source.flags & TypeFlags.Never) { + return emptyObjectType; + } + + if (source.flags & TypeFlags.Union) { + return mapType(source, t => getRestType(t, properties, symbol)); + } + const members = createMap(); const names = createMap(); for (const name of properties) { @@ -3095,7 +3105,7 @@ namespace ts { let type: Type; if (pattern.kind === SyntaxKind.ObjectBindingPattern) { if (declaration.dotDotDotToken) { - if (!(parentType.flags & TypeFlags.Object)) { + if (!isValidSpreadType(parentType)) { error(declaration, Diagnostics.Rest_types_may_only_be_created_from_object_types); return unknownType; } @@ -3309,14 +3319,19 @@ namespace ts { // Return the type implied by an object binding pattern function getTypeFromObjectBindingPattern(pattern: ObjectBindingPattern, includePatternInType: boolean, reportErrors: boolean): Type { const members = createMap(); + let stringIndexInfo: IndexInfo; let hasComputedProperties = false; forEach(pattern.elements, e => { const name = e.propertyName || e.name; - if (isComputedNonLiteralName(name) || e.dotDotDotToken) { - // do not include computed properties or rests in the implied type + if (isComputedNonLiteralName(name)) { + // do not include computed properties in the implied type hasComputedProperties = true; return; } + if (e.dotDotDotToken) { + stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false); + return; + } const text = getTextOfPropertyName(name); const flags = SymbolFlags.Property | SymbolFlags.Transient | (e.initializer ? SymbolFlags.Optional : 0); @@ -3325,7 +3340,7 @@ namespace ts { symbol.bindingElement = e; members[symbol.name] = symbol; }); - const result = createAnonymousType(undefined, members, emptyArray, emptyArray, undefined, undefined); + const result = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, undefined); if (includePatternInType) { result.pattern = pattern; } @@ -4524,7 +4539,7 @@ namespace ts { const isomorphicProp = isomorphicType && getPropertyOfType(isomorphicType, propName); const isOptional = templateOptional || !!(isomorphicProp && isomorphicProp.flags & SymbolFlags.Optional); const prop = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | (isOptional ? SymbolFlags.Optional : 0), propName); - prop.type = addOptionality(propType, isOptional); + prop.type = propType; prop.isReadonly = templateReadonly || isomorphicProp && isReadonlySymbol(isomorphicProp); members[propName] = prop; } @@ -4548,7 +4563,7 @@ namespace ts { function getTemplateTypeFromMappedType(type: MappedType) { return type.templateType || (type.templateType = type.declaration.type ? - instantiateType(getTypeFromTypeNode(type.declaration.type), type.mapper || identityMapper) : + instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), !!type.declaration.questionToken), type.mapper || identityMapper) : unknownType); } @@ -6013,7 +6028,7 @@ namespace ts { } const mapper = createUnaryTypeMapper(getTypeParameterFromMappedType(type), indexType); const templateMapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper; - return addOptionality(instantiateType(getTemplateTypeFromMappedType(type), templateMapper), !!type.declaration.questionToken); + return instantiateType(getTemplateTypeFromMappedType(type), templateMapper); } function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode) { @@ -6110,11 +6125,25 @@ namespace ts { * this function should be called in a left folding style, with left = previous result of getSpreadType * and right = the new element to be spread. */ - function getSpreadType(left: Type, right: Type, isFromObjectLiteral: boolean): ResolvedType | IntrinsicType { - Debug.assert(!!(left.flags & (TypeFlags.Object | TypeFlags.Any)) && !!(right.flags & (TypeFlags.Object | TypeFlags.Any)), "Only object types may be spread."); + function getSpreadType(left: Type, right: Type, isFromObjectLiteral: boolean): Type { if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) { return anyType; } + left = filterType(left, t => !(t.flags & TypeFlags.Nullable)); + if (left.flags & TypeFlags.Never) { + return right; + } + right = filterType(right, t => !(t.flags & TypeFlags.Nullable)); + if (right.flags & TypeFlags.Never) { + return left; + } + if (left.flags & TypeFlags.Union) { + return mapType(left, t => getSpreadType(t, right, isFromObjectLiteral)); + } + if (right.flags & TypeFlags.Union) { + return mapType(right, t => getSpreadType(left, t, isFromObjectLiteral)); + } + const members = createMap(); const skippedPrivateMembers = createMap(); let stringIndexInfo: IndexInfo; @@ -8462,16 +8491,18 @@ namespace ts { const typeInferences = createTypeInferencesObject(); const typeInferencesArray = [typeInferences]; const templateType = getTemplateTypeFromMappedType(target); + const readonlyMask = target.declaration.readonlyToken ? false : true; + const optionalMask = target.declaration.questionToken ? 0 : SymbolFlags.Optional; const properties = getPropertiesOfType(source); const members = createSymbolTable(properties); let hasInferredTypes = false; for (const prop of properties) { const inferredPropType = inferTargetType(getTypeOfSymbol(prop)); if (inferredPropType) { - const inferredProp = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | prop.flags & SymbolFlags.Optional, prop.name); + const inferredProp = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | prop.flags & optionalMask, prop.name); inferredProp.declarations = prop.declarations; inferredProp.type = inferredPropType; - inferredProp.isReadonly = isReadonlySymbol(prop); + inferredProp.isReadonly = readonlyMask && isReadonlySymbol(prop); members[prop.name] = inferredProp; hasInferredTypes = true; } @@ -8480,7 +8511,7 @@ namespace ts { if (indexInfo) { const inferredIndexType = inferTargetType(indexInfo.type); if (inferredIndexType) { - indexInfo = createIndexInfo(inferredIndexType, indexInfo.isReadonly); + indexInfo = createIndexInfo(inferredIndexType, readonlyMask && indexInfo.isReadonly); hasInferredTypes = true; } } @@ -11421,7 +11452,8 @@ namespace ts { if (impliedProp) { prop.flags |= impliedProp.flags & SymbolFlags.Optional; } - else if (!compilerOptions.suppressExcessPropertyErrors) { + + else if (!compilerOptions.suppressExcessPropertyErrors && !getIndexInfoOfType(contextualType, IndexKind.String)) { error(memberDecl.name, Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(member), typeToString(contextualType)); } @@ -11437,6 +11469,9 @@ namespace ts { member = prop; } else if (memberDecl.kind === SyntaxKind.SpreadAssignment) { + if (languageVersion < ScriptTarget.ESNext) { + checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign); + } if (propertiesArray.length > 0) { spread = getSpreadType(spread, createObjectLiteralType(), /*isFromObjectLiteral*/ true); propertiesArray = []; @@ -11446,7 +11481,7 @@ namespace ts { typeFlags = 0; } const type = checkExpression((memberDecl as SpreadAssignment).expression); - if (!(type.flags & (TypeFlags.Object | TypeFlags.Any))) { + if (!isValidSpreadType(type)) { error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types); return unknownType; } @@ -11524,6 +11559,12 @@ namespace ts { } } + function isValidSpreadType(type: Type): boolean { + return !!(type.flags & (TypeFlags.Any | TypeFlags.Null | TypeFlags.Undefined) || + type.flags & TypeFlags.Object && !isGenericMappedType(type) || + type.flags & TypeFlags.UnionOrIntersection && !forEach((type).types, t => !isValidSpreadType(t))); + } + function checkJsxSelfClosingElement(node: JsxSelfClosingElement) { checkJsxOpeningLikeElement(node); return jsxElementType || anyType; @@ -11624,6 +11665,9 @@ namespace ts { } function checkJsxSpreadAttribute(node: JsxSpreadAttribute, elementAttributesType: Type, nameTable: Map) { + if (compilerOptions.jsx === JsxEmit.React) { + checkExternalEmitHelpers(node, ExternalEmitHelpers.Assign); + } const type = checkExpression(node.expression); const props = getPropertiesOfType(type); for (const prop of props) { @@ -14389,6 +14433,9 @@ namespace ts { } } else if (property.kind === SyntaxKind.SpreadAssignment) { + if (languageVersion < ScriptTarget.ESNext) { + checkExternalEmitHelpers(property, ExternalEmitHelpers.Rest); + } const nonRestNames: PropertyName[] = []; if (allProperties) { for (let i = 0; i < allProperties.length - 1; i++) { @@ -15301,6 +15348,13 @@ namespace ts { checkGrammarFunctionLikeDeclaration(node); } + if (isAsyncFunctionLike(node) && languageVersion < ScriptTarget.ES2017) { + checkExternalEmitHelpers(node, ExternalEmitHelpers.Awaiter); + if (languageVersion < ScriptTarget.ES2015) { + checkExternalEmitHelpers(node, ExternalEmitHelpers.Generator); + } + } + checkTypeParameters(node.typeParameters); forEach(node.parameters, checkParameter); @@ -16436,7 +16490,15 @@ namespace ts { error(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning); } + const firstDecorator = node.decorators[0]; + checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Decorate); + if (node.kind === SyntaxKind.Parameter) { + checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Param); + } + if (compilerOptions.emitDecoratorMetadata) { + checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Metadata); + // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator. switch (node.kind) { case SyntaxKind.ClassDeclaration: @@ -16823,7 +16885,7 @@ namespace ts { } function checkCollisionWithGlobalPromiseInGeneratedCode(node: Node, name: Identifier): void { - if (!needCollisionCheckForIdentifier(node, name, "Promise")) { + if (languageVersion >= ScriptTarget.ES2017 || !needCollisionCheckForIdentifier(node, name, "Promise")) { return; } @@ -17000,6 +17062,9 @@ namespace ts { } if (node.kind === SyntaxKind.BindingElement) { + if (node.parent.kind === SyntaxKind.ObjectBindingPattern && languageVersion < ScriptTarget.ESNext) { + checkExternalEmitHelpers(node, ExternalEmitHelpers.Rest); + } // check computed properties inside property names of binding elements if (node.propertyName && node.propertyName.kind === SyntaxKind.ComputedPropertyName) { checkComputedPropertyName(node.propertyName); @@ -17917,6 +17982,10 @@ namespace ts { const baseTypeNode = getClassExtendsHeritageClauseElement(node); if (baseTypeNode) { + if (languageVersion < ScriptTarget.ES2015) { + checkExternalEmitHelpers(baseTypeNode.parent, ExternalEmitHelpers.Extends); + } + const baseTypes = getBaseTypes(type); if (baseTypes.length && produceDiagnostics) { const baseType = baseTypes[0]; @@ -20357,8 +20426,6 @@ namespace ts { // Initialize global symbol table let augmentations: LiteralExpression[][]; - let requestedExternalEmitHelpers: NodeFlags = 0; - let firstFileRequestingExternalHelpers: SourceFile; for (const file of host.getSourceFiles()) { if (!isExternalOrCommonJsModule(file)) { mergeSymbolTable(globals, file.locals); @@ -20378,15 +20445,6 @@ namespace ts { } } } - if ((compilerOptions.isolatedModules || isExternalModule(file)) && !file.isDeclarationFile) { - const fileRequestedExternalEmitHelpers = file.flags & NodeFlags.EmitHelperFlags; - if (fileRequestedExternalEmitHelpers) { - requestedExternalEmitHelpers |= fileRequestedExternalEmitHelpers; - if (firstFileRequestingExternalHelpers === undefined) { - firstFileRequestingExternalHelpers = file; - } - } - } } if (augmentations) { @@ -20452,57 +20510,51 @@ namespace ts { const symbol = getGlobalSymbol("ReadonlyArray", SymbolFlags.Type, /*diagnostic*/ undefined); globalReadonlyArrayType = symbol && getTypeOfGlobalSymbol(symbol, /*arity*/ 1); anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType; + } - // If we have specified that we are importing helpers, we should report global - // errors if we cannot resolve the helpers external module, or if it does not have - // the necessary helpers exported. - if (compilerOptions.importHelpers && firstFileRequestingExternalHelpers) { - // Find the first reference to the helpers module. - const helpersModule = resolveExternalModule( - firstFileRequestingExternalHelpers, - externalHelpersModuleNameText, - Diagnostics.Cannot_find_module_0, - /*errorNode*/ undefined); - - // If we found the module, report errors if it does not have the necessary exports. - if (helpersModule) { - const exports = helpersModule.exports; - if (requestedExternalEmitHelpers & NodeFlags.HasClassExtends && languageVersion < ScriptTarget.ES2015) { - verifyHelperSymbol(exports, "__extends", SymbolFlags.Value); - } - if (requestedExternalEmitHelpers & NodeFlags.HasSpreadAttribute && - (languageVersion < ScriptTarget.ESNext || compilerOptions.jsx === JsxEmit.React)) { - verifyHelperSymbol(exports, "__assign", SymbolFlags.Value); - } - if (languageVersion < ScriptTarget.ESNext && requestedExternalEmitHelpers & NodeFlags.HasRestAttribute) { - verifyHelperSymbol(exports, "__rest", SymbolFlags.Value); - } - if (requestedExternalEmitHelpers & NodeFlags.HasDecorators) { - verifyHelperSymbol(exports, "__decorate", SymbolFlags.Value); - if (compilerOptions.emitDecoratorMetadata) { - verifyHelperSymbol(exports, "__metadata", SymbolFlags.Value); - } - } - if (requestedExternalEmitHelpers & NodeFlags.HasParamDecorators) { - verifyHelperSymbol(exports, "__param", SymbolFlags.Value); - } - if (requestedExternalEmitHelpers & NodeFlags.HasAsyncFunctions) { - verifyHelperSymbol(exports, "__awaiter", SymbolFlags.Value); - if (languageVersion < ScriptTarget.ES2015) { - verifyHelperSymbol(exports, "__generator", SymbolFlags.Value); + function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) { + if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) { + const sourceFile = getSourceFileOfNode(location); + if (isEffectiveExternalModule(sourceFile, compilerOptions)) { + const helpersModule = resolveHelpersModule(sourceFile, location); + if (helpersModule !== unknownSymbol) { + const uncheckedHelpers = helpers & ~requestedExternalEmitHelpers; + for (let helper = ExternalEmitHelpers.FirstEmitHelper; helper <= ExternalEmitHelpers.LastEmitHelper; helper <<= 1) { + if (uncheckedHelpers & helper) { + const name = getHelperName(helper); + const symbol = getSymbol(helpersModule.exports, escapeIdentifier(name), SymbolFlags.Value); + if (!symbol) { + error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1, externalHelpersModuleNameText, name); + } + } } } + requestedExternalEmitHelpers |= helpers; } } } - function verifyHelperSymbol(symbols: SymbolTable, name: string, meaning: SymbolFlags) { - const symbol = getSymbol(symbols, escapeIdentifier(name), meaning); - if (!symbol) { - error(/*location*/ undefined, Diagnostics.Module_0_has_no_exported_member_1, externalHelpersModuleNameText, name); + function getHelperName(helper: ExternalEmitHelpers) { + switch (helper) { + case ExternalEmitHelpers.Extends: return "__extends"; + case ExternalEmitHelpers.Assign: return "__assign"; + case ExternalEmitHelpers.Rest: return "__rest"; + case ExternalEmitHelpers.Decorate: return "__decorate"; + case ExternalEmitHelpers.Metadata: return "__metadata"; + case ExternalEmitHelpers.Param: return "__param"; + case ExternalEmitHelpers.Awaiter: return "__awaiter"; + case ExternalEmitHelpers.Generator: return "__generator"; + } + } + + function resolveHelpersModule(node: SourceFile, errorNode: Node) { + if (!externalHelpersModule) { + externalHelpersModule = resolveExternalModule(node, externalHelpersModuleNameText, Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol; } + return externalHelpersModule; } + function createInstantiatedPromiseLikeType(): ObjectType { const promiseLikeType = getGlobalPromiseLikeType(); if (promiseLikeType !== emptyGenericType) { diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index fd2740f20c2e6..38e0db0ba6b74 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -1625,6 +1625,12 @@ namespace ts { Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1; + case SyntaxKind.IndexSignature: + // Interfaces cannot have parameter types that cannot be named + return symbolAccessibilityResult.errorModuleName ? + Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : + Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1; + case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: if (hasModifier(node.parent, ModifierFlags.Static)) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 8f3b9beb888ad..5f49c54a2af22 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1027,6 +1027,10 @@ "category": "Error", "code": 2342 }, + "This syntax requires an imported helper named '{1}', but module '{0}' has no exported member '{1}'.": { + "category": "Error", + "code": 2343 + }, "Type '{0}' does not satisfy the constraint '{1}'.": { "category": "Error", "code": 2344 @@ -1067,6 +1071,10 @@ "category": "Error", "code": 2353 }, + "This syntax requires an imported helper but module '{0}' cannot be found.": { + "category": "Error", + "code": 2354 + }, "A function whose declared type is neither 'void' nor 'any' must return a value.": { "category": "Error", "code": 2355 @@ -2292,6 +2300,14 @@ "category": "Message", "code": 4090 }, + "Parameter '{0}' of index signature from exported interface has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4091 + }, + "Parameter '{0}' of index signature from exported interface has or is using private name '{1}'.": { + "category": "Error", + "code": 4092 + }, "The current host does not support the '{0}' option.": { "category": "Error", diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 43590791c83c6..8e32259ff0f2d 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -459,7 +459,7 @@ namespace ts { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; - if (typeof Object.getOwnPropertySymbols === "function") + if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]]; return t; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 219e7efa90a23..bc400df257d9e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -418,26 +418,20 @@ namespace ts { HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding) HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding) GlobalAugmentation = 1 << 9, // Set if module declaration is an augmentation for the global scope - HasClassExtends = 1 << 10, // If the file has a non-ambient class with an extends clause in ES5 or lower (initialized by binding) - HasDecorators = 1 << 11, // If the file has decorators (initialized by binding) - HasParamDecorators = 1 << 12, // If the file has parameter decorators (initialized by binding) - HasAsyncFunctions = 1 << 13, // If the file has async functions (initialized by binding) - HasSpreadAttribute = 1 << 14, // If the file as JSX spread attributes (initialized by binding) - HasRestAttribute = 1 << 15, // If the file has object destructure elements - DisallowInContext = 1 << 16, // If node was parsed in a context where 'in-expressions' are not allowed - YieldContext = 1 << 17, // If node was parsed in the 'yield' context created when parsing a generator - DecoratorContext = 1 << 18, // If node was parsed as part of a decorator - AwaitContext = 1 << 19, // If node was parsed in the 'await' context created when parsing an async function - ThisNodeHasError = 1 << 20, // If the parser encountered an error when parsing the code that created this node - JavaScriptFile = 1 << 21, // If node was parsed in a JavaScript - ThisNodeOrAnySubNodesHasError = 1 << 22, // If this node or any of its children had an error - HasAggregatedChildData = 1 << 23, // If we've computed data from children and cached it in this node + HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding) + DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed + YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator + DecoratorContext = 1 << 13, // If node was parsed as part of a decorator + AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function + ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node + JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript + ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error + HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node BlockScoped = Let | Const, ReachabilityCheckFlags = HasImplicitReturn | HasExplicitReturn, - EmitHelperFlags = HasClassExtends | HasDecorators | HasParamDecorators | HasAsyncFunctions | HasSpreadAttribute | HasRestAttribute, - ReachabilityAndEmitFlags = ReachabilityCheckFlags | EmitHelperFlags, + ReachabilityAndEmitFlags = ReachabilityCheckFlags | HasAsyncFunctions, // Parsing context flags ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile, @@ -3698,6 +3692,25 @@ namespace ts { readonly priority?: number; // Helpers with a higher priority are emitted earlier than other helpers on the node. } + /** + * Used by the checker, this enum keeps track of external emit helpers that should be type + * checked. + */ + /* @internal */ + export const enum ExternalEmitHelpers { + Extends = 1 << 0, // __extends (used by the ES2015 class transformation) + Assign = 1 << 1, // __assign (used by Jsx and ESNext object spread transformations) + Rest = 1 << 2, // __rest (used by ESNext object rest transformation) + Decorate = 1 << 3, // __decorate (used by TypeScript decorators transformation) + Metadata = 1 << 4, // __metadata (used by TypeScript decorators transformation) + Param = 1 << 5, // __param (used by TypeScript decorators transformation) + Awaiter = 1 << 6, // __awaiter (used by ES2017 async functions transformation) + Generator = 1 << 7, // __generator (used by ES2015 generator transformation) + + FirstEmitHelper = Extends, + LastEmitHelper = Generator + } + /* @internal */ export const enum EmitContext { SourceFile, // Emitting a SourceFile diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 363ddf0de801c..4fa0c60dce7c5 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -423,6 +423,10 @@ namespace ts { return false; } + export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) { + return isExternalModule(node) || compilerOptions.isolatedModules; + } + export function isBlockScope(node: Node, parentNode: Node) { switch (node.kind) { case SyntaxKind.SourceFile: diff --git a/tests/baselines/reference/declarationEmitIndexTypeNotFound.errors.txt b/tests/baselines/reference/declarationEmitIndexTypeNotFound.errors.txt new file mode 100644 index 0000000000000..ffbfd25fa949f --- /dev/null +++ b/tests/baselines/reference/declarationEmitIndexTypeNotFound.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/declarationEmitIndexTypeNotFound.ts(3,6): error TS1023: An index signature parameter type must be 'string' or 'number'. +tests/cases/compiler/declarationEmitIndexTypeNotFound.ts(3,13): error TS2304: Cannot find name 'TypeNotFound'. +tests/cases/compiler/declarationEmitIndexTypeNotFound.ts(3,13): error TS4092: Parameter 'index' of index signature from exported interface has or is using private name 'TypeNotFound'. + + +==== tests/cases/compiler/declarationEmitIndexTypeNotFound.ts (3 errors) ==== + + export interface Test { + [index: TypeNotFound]: any; + ~~~~~ +!!! error TS1023: An index signature parameter type must be 'string' or 'number'. + ~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'TypeNotFound'. + ~~~~~~~~~~~~ +!!! error TS4092: Parameter 'index' of index signature from exported interface has or is using private name 'TypeNotFound'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitIndexTypeNotFound.js b/tests/baselines/reference/declarationEmitIndexTypeNotFound.js new file mode 100644 index 0000000000000..22100e5cb7229 --- /dev/null +++ b/tests/baselines/reference/declarationEmitIndexTypeNotFound.js @@ -0,0 +1,9 @@ +//// [declarationEmitIndexTypeNotFound.ts] + +export interface Test { + [index: TypeNotFound]: any; +} + + +//// [declarationEmitIndexTypeNotFound.js] +"use strict"; diff --git a/tests/baselines/reference/importHelpersNoHelpers.errors.txt b/tests/baselines/reference/importHelpersNoHelpers.errors.txt index fa9a935c8d811..a0c089a9ddc26 100644 --- a/tests/baselines/reference/importHelpersNoHelpers.errors.txt +++ b/tests/baselines/reference/importHelpersNoHelpers.errors.txt @@ -1,32 +1,38 @@ -error TS2305: Module 'tslib' has no exported member '__assign'. -error TS2305: Module 'tslib' has no exported member '__decorate'. -error TS2305: Module 'tslib' has no exported member '__extends'. -error TS2305: Module 'tslib' has no exported member '__metadata'. -error TS2305: Module 'tslib' has no exported member '__param'. -error TS2305: Module 'tslib' has no exported member '__rest'. +tests/cases/compiler/external.ts(2,16): error TS2343: This syntax requires an imported helper named '__extends', but module 'tslib' has no exported member '__extends'. +tests/cases/compiler/external.ts(6,1): error TS2343: This syntax requires an imported helper named '__decorate', but module 'tslib' has no exported member '__decorate'. +tests/cases/compiler/external.ts(6,1): error TS2343: This syntax requires an imported helper named '__metadata', but module 'tslib' has no exported member '__metadata'. +tests/cases/compiler/external.ts(8,12): error TS2343: This syntax requires an imported helper named '__param', but module 'tslib' has no exported member '__param'. +tests/cases/compiler/external.ts(13,13): error TS2343: This syntax requires an imported helper named '__assign', but module 'tslib' has no exported member '__assign'. +tests/cases/compiler/external.ts(14,12): error TS2343: This syntax requires an imported helper named '__rest', but module 'tslib' has no exported member '__rest'. -!!! error TS2305: Module 'tslib' has no exported member '__assign'. -!!! error TS2305: Module 'tslib' has no exported member '__decorate'. -!!! error TS2305: Module 'tslib' has no exported member '__extends'. -!!! error TS2305: Module 'tslib' has no exported member '__metadata'. -!!! error TS2305: Module 'tslib' has no exported member '__param'. -!!! error TS2305: Module 'tslib' has no exported member '__rest'. -==== tests/cases/compiler/external.ts (0 errors) ==== +==== tests/cases/compiler/external.ts (6 errors) ==== export class A { } export class B extends A { } + ~~~~~~~~~ +!!! error TS2343: This syntax requires an imported helper named '__extends', but module 'tslib' has no exported member '__extends'. declare var dec: any; @dec + ~~~~ +!!! error TS2343: This syntax requires an imported helper named '__decorate', but module 'tslib' has no exported member '__decorate'. + ~~~~ +!!! error TS2343: This syntax requires an imported helper named '__metadata', but module 'tslib' has no exported member '__metadata'. class C { method(@dec x: number) { + ~~~~ +!!! error TS2343: This syntax requires an imported helper named '__param', but module 'tslib' has no exported member '__param'. } } const o = { a: 1 }; const y = { ...o }; + ~~~~ +!!! error TS2343: This syntax requires an imported helper named '__assign', but module 'tslib' has no exported member '__assign'. const { ...x } = y; + ~ +!!! error TS2343: This syntax requires an imported helper named '__rest', but module 'tslib' has no exported member '__rest'. ==== tests/cases/compiler/script.ts (0 errors) ==== class A { } diff --git a/tests/baselines/reference/importHelpersNoModule.errors.txt b/tests/baselines/reference/importHelpersNoModule.errors.txt index d59fd0537ca5d..b6786ec363552 100644 --- a/tests/baselines/reference/importHelpersNoModule.errors.txt +++ b/tests/baselines/reference/importHelpersNoModule.errors.txt @@ -1,10 +1,11 @@ -error TS2307: Cannot find module 'tslib'. +tests/cases/compiler/external.ts(2,16): error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found. -!!! error TS2307: Cannot find module 'tslib'. -==== tests/cases/compiler/external.ts (0 errors) ==== +==== tests/cases/compiler/external.ts (1 errors) ==== export class A { } export class B extends A { } + ~~~~~~~~~ +!!! error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found. declare var dec: any; diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.js b/tests/baselines/reference/isomorphicMappedTypeInference.js index 0fc646043dcb7..87f3e1c40173d 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.js +++ b/tests/baselines/reference/isomorphicMappedTypeInference.js @@ -103,6 +103,21 @@ function f6(s: string) { }); let v = unboxify(b); let x: string | number | boolean = v[s]; +} + +declare function validate(obj: { [P in keyof T]?: T[P] }): T; +declare function clone(obj: { readonly [P in keyof T]: T[P] }): T; +declare function validateAndClone(obj: { readonly [P in keyof T]?: T[P] }): T; + +type Foo = { + a?: number; + readonly b: string; +} + +function f10(foo: Foo) { + let x = validate(foo); // { a: number, readonly b: string } + let y = clone(foo); // { a?: number, b: string } + let z = validateAndClone(foo); // { a: number, b: string } } //// [isomorphicMappedTypeInference.js] @@ -190,6 +205,11 @@ function f6(s) { var v = unboxify(b); var x = v[s]; } +function f10(foo) { + var x = validate(foo); // { a: number, readonly b: string } + var y = clone(foo); // { a?: number, b: string } + var z = validateAndClone(foo); // { a: number, b: string } +} //// [isomorphicMappedTypeInference.d.ts] @@ -220,3 +240,17 @@ declare function makeDictionary(obj: { [x: string]: T; }; declare function f6(s: string): void; +declare function validate(obj: { + [P in keyof T]?: T[P]; +}): T; +declare function clone(obj: { + readonly [P in keyof T]: T[P]; +}): T; +declare function validateAndClone(obj: { + readonly [P in keyof T]?: T[P]; +}): T; +declare type Foo = { + a?: number; + readonly b: string; +}; +declare function f10(foo: Foo): void; diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.symbols b/tests/baselines/reference/isomorphicMappedTypeInference.symbols index 62dcc6316bcf7..3e8a92e769109 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.symbols +++ b/tests/baselines/reference/isomorphicMappedTypeInference.symbols @@ -332,3 +332,64 @@ function f6(s: string) { >v : Symbol(v, Decl(isomorphicMappedTypeInference.ts, 102, 7)) >s : Symbol(s, Decl(isomorphicMappedTypeInference.ts, 96, 12)) } + +declare function validate(obj: { [P in keyof T]?: T[P] }): T; +>validate : Symbol(validate, Decl(isomorphicMappedTypeInference.ts, 104, 1)) +>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 106, 26)) +>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 106, 29)) +>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 106, 37)) +>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 106, 26)) +>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 106, 26)) +>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 106, 37)) +>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 106, 26)) + +declare function clone(obj: { readonly [P in keyof T]: T[P] }): T; +>clone : Symbol(clone, Decl(isomorphicMappedTypeInference.ts, 106, 64)) +>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 107, 23)) +>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 107, 26)) +>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 107, 43)) +>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 107, 23)) +>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 107, 23)) +>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 107, 43)) +>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 107, 23)) + +declare function validateAndClone(obj: { readonly [P in keyof T]?: T[P] }): T; +>validateAndClone : Symbol(validateAndClone, Decl(isomorphicMappedTypeInference.ts, 107, 69)) +>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 108, 34)) +>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 108, 37)) +>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 108, 54)) +>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 108, 34)) +>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 108, 34)) +>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 108, 54)) +>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 108, 34)) + +type Foo = { +>Foo : Symbol(Foo, Decl(isomorphicMappedTypeInference.ts, 108, 81)) + + a?: number; +>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 110, 12)) + + readonly b: string; +>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 111, 15)) +} + +function f10(foo: Foo) { +>f10 : Symbol(f10, Decl(isomorphicMappedTypeInference.ts, 113, 1)) +>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 115, 13)) +>Foo : Symbol(Foo, Decl(isomorphicMappedTypeInference.ts, 108, 81)) + + let x = validate(foo); // { a: number, readonly b: string } +>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 116, 7)) +>validate : Symbol(validate, Decl(isomorphicMappedTypeInference.ts, 104, 1)) +>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 115, 13)) + + let y = clone(foo); // { a?: number, b: string } +>y : Symbol(y, Decl(isomorphicMappedTypeInference.ts, 117, 7)) +>clone : Symbol(clone, Decl(isomorphicMappedTypeInference.ts, 106, 64)) +>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 115, 13)) + + let z = validateAndClone(foo); // { a: number, b: string } +>z : Symbol(z, Decl(isomorphicMappedTypeInference.ts, 118, 7)) +>validateAndClone : Symbol(validateAndClone, Decl(isomorphicMappedTypeInference.ts, 107, 69)) +>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 115, 13)) +} diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.types b/tests/baselines/reference/isomorphicMappedTypeInference.types index 00a80639f732c..eee2d6cbe7d40 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.types +++ b/tests/baselines/reference/isomorphicMappedTypeInference.types @@ -403,3 +403,67 @@ function f6(s: string) { >v : { [x: string]: string | number | boolean; } >s : string } + +declare function validate(obj: { [P in keyof T]?: T[P] }): T; +>validate : (obj: { [P in keyof T]?: T[P] | undefined; }) => T +>T : T +>obj : { [P in keyof T]?: T[P] | undefined; } +>P : P +>T : T +>T : T +>P : P +>T : T + +declare function clone(obj: { readonly [P in keyof T]: T[P] }): T; +>clone : (obj: { readonly [P in keyof T]: T[P]; }) => T +>T : T +>obj : { readonly [P in keyof T]: T[P]; } +>P : P +>T : T +>T : T +>P : P +>T : T + +declare function validateAndClone(obj: { readonly [P in keyof T]?: T[P] }): T; +>validateAndClone : (obj: { readonly [P in keyof T]?: T[P] | undefined; }) => T +>T : T +>obj : { readonly [P in keyof T]?: T[P] | undefined; } +>P : P +>T : T +>T : T +>P : P +>T : T + +type Foo = { +>Foo : Foo + + a?: number; +>a : number | undefined + + readonly b: string; +>b : string +} + +function f10(foo: Foo) { +>f10 : (foo: Foo) => void +>foo : Foo +>Foo : Foo + + let x = validate(foo); // { a: number, readonly b: string } +>x : { a: number; readonly b: string; } +>validate(foo) : { a: number; readonly b: string; } +>validate : (obj: { [P in keyof T]?: T[P] | undefined; }) => T +>foo : Foo + + let y = clone(foo); // { a?: number, b: string } +>y : { a?: number | undefined; b: string; } +>clone(foo) : { a?: number | undefined; b: string; } +>clone : (obj: { readonly [P in keyof T]: T[P]; }) => T +>foo : Foo + + let z = validateAndClone(foo); // { a: number, b: string } +>z : { a: number; b: string; } +>validateAndClone(foo) : { a: number; b: string; } +>validateAndClone : (obj: { readonly [P in keyof T]?: T[P] | undefined; }) => T +>foo : Foo +} diff --git a/tests/baselines/reference/mappedTypeErrors.errors.txt b/tests/baselines/reference/mappedTypeErrors.errors.txt index b3cba7eb54d6a..945652bf92956 100644 --- a/tests/baselines/reference/mappedTypeErrors.errors.txt +++ b/tests/baselines/reference/mappedTypeErrors.errors.txt @@ -16,9 +16,9 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(38,24): error TS2344: T Type 'T' is not assignable to type '"visible"'. Type 'string | number' is not assignable to type '"visible"'. Type 'string' is not assignable to type '"visible"'. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(60,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]?: T[P]; }'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(60,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]?: T[P] | undefined; }'. tests/cases/conformance/types/mapped/mappedTypeErrors.ts(61,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]: T[P]; }'. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(62,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]?: T[P]; }'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(62,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]?: T[P] | undefined; }'. tests/cases/conformance/types/mapped/mappedTypeErrors.ts(67,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]: T[P][]; }'. @@ -112,13 +112,13 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(67,9): error TS2403: Su var x: { [P in keyof T]: T[P] }; var x: { [P in keyof T]?: T[P] }; // Error ~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]?: T[P]; }'. +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]?: T[P] | undefined; }'. var x: { readonly [P in keyof T]: T[P] }; // Error ~ !!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]: T[P]; }'. var x: { readonly [P in keyof T]?: T[P] }; // Error ~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]?: T[P]; }'. +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]?: T[P] | undefined; }'. } function f12() { diff --git a/tests/baselines/reference/objectRest.js b/tests/baselines/reference/objectRest.js index 85d8a6a573e37..48a1bf8daf853 100644 --- a/tests/baselines/reference/objectRest.js +++ b/tests/baselines/reference/objectRest.js @@ -36,6 +36,8 @@ let computed = 'b'; let computed2 = 'a'; var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o; ({ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o); + +var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes']; //// [objectRest.js] @@ -43,7 +45,7 @@ var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; - if (typeof Object.getOwnPropertySymbols === "function") + if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]]; return t; @@ -76,4 +78,8 @@ let computed = 'b'; let computed2 = 'a'; var _g = computed, stillNotGreat = o[_g], _h = computed2, soSo = o[_h], o = __rest(o, [typeof _g === "symbol" ? _g : _g + "", typeof _h === "symbol" ? _h : _h + ""]); (_j = computed, stillNotGreat = o[_j], _k = computed2, soSo = o[_k], o = __rest(o, [typeof _j === "symbol" ? _j : _j + "", typeof _k === "symbol" ? _k : _k + ""])); +var noContextualType = (_a) => { + var { aNumber = 12 } = _a, notEmptyObject = __rest(_a, ["aNumber"]); + return aNumber + notEmptyObject['anythingGoes']; +}; var _d, _f, _j, _k; diff --git a/tests/baselines/reference/objectRest.symbols b/tests/baselines/reference/objectRest.symbols index 325258aa8cd6c..4630939213515 100644 --- a/tests/baselines/reference/objectRest.symbols +++ b/tests/baselines/reference/objectRest.symbols @@ -169,3 +169,10 @@ var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o; >o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51)) >o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 35, 51)) +var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes']; +>noContextualType : Symbol(noContextualType, Decl(objectRest.ts, 38, 3)) +>aNumber : Symbol(aNumber, Decl(objectRest.ts, 38, 25)) +>notEmptyObject : Symbol(notEmptyObject, Decl(objectRest.ts, 38, 39)) +>aNumber : Symbol(aNumber, Decl(objectRest.ts, 38, 25)) +>notEmptyObject : Symbol(notEmptyObject, Decl(objectRest.ts, 38, 39)) + diff --git a/tests/baselines/reference/objectRest.types b/tests/baselines/reference/objectRest.types index 7d8335437472f..1dc0574171344 100644 --- a/tests/baselines/reference/objectRest.types +++ b/tests/baselines/reference/objectRest.types @@ -195,3 +195,15 @@ var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o; >o : { a: number; b: string; } >o : { a: number; b: string; } +var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes']; +>noContextualType : ({aNumber, ...notEmptyObject}: { [x: string]: any; aNumber?: number; }) => any +>({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes'] : ({aNumber, ...notEmptyObject}: { [x: string]: any; aNumber?: number; }) => any +>aNumber : number +>12 : 12 +>notEmptyObject : { [x: string]: any; } +>aNumber + notEmptyObject['anythingGoes'] : any +>aNumber : number +>notEmptyObject['anythingGoes'] : any +>notEmptyObject : { [x: string]: any; } +>'anythingGoes' : "anythingGoes" + diff --git a/tests/baselines/reference/objectRestAssignment.js b/tests/baselines/reference/objectRestAssignment.js index 66ee00f669635..cbdff663c2676 100644 --- a/tests/baselines/reference/objectRestAssignment.js +++ b/tests/baselines/reference/objectRestAssignment.js @@ -19,7 +19,7 @@ var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; - if (typeof Object.getOwnPropertySymbols === "function") + if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]]; return t; diff --git a/tests/baselines/reference/objectRestForOf.js b/tests/baselines/reference/objectRestForOf.js index b4e33550cb05f..fd81f77512e19 100644 --- a/tests/baselines/reference/objectRestForOf.js +++ b/tests/baselines/reference/objectRestForOf.js @@ -27,7 +27,7 @@ var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; - if (typeof Object.getOwnPropertySymbols === "function") + if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]]; return t; diff --git a/tests/baselines/reference/objectRestNegative.errors.txt b/tests/baselines/reference/objectRestNegative.errors.txt index 345e99723bd66..6e65af4bdc138 100644 --- a/tests/baselines/reference/objectRestNegative.errors.txt +++ b/tests/baselines/reference/objectRestNegative.errors.txt @@ -3,11 +3,14 @@ tests/cases/conformance/types/rest/objectRestNegative.ts(6,10): error TS2322: Ty Types of property 'a' are incompatible. Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/rest/objectRestNegative.ts(9,31): error TS2462: A rest element must be last in a destructuring pattern +tests/cases/conformance/types/rest/objectRestNegative.ts(11,30): error TS7008: Member 'x' implicitly has an 'any' type. +tests/cases/conformance/types/rest/objectRestNegative.ts(11,33): error TS7008: Member 'y' implicitly has an 'any' type. tests/cases/conformance/types/rest/objectRestNegative.ts(12,17): error TS2700: Rest types may only be created from object types. tests/cases/conformance/types/rest/objectRestNegative.ts(17,9): error TS2701: The target of an object rest assignment must be a variable or a property access. +tests/cases/conformance/types/rest/objectRestNegative.ts(19,90): error TS2339: Property 'anythingGoes' does not exist on type '{ [x: string]: any; }'. -==== tests/cases/conformance/types/rest/objectRestNegative.ts (5 errors) ==== +==== tests/cases/conformance/types/rest/objectRestNegative.ts (8 errors) ==== let o = { a: 1, b: 'no' }; var { ...mustBeLast, a } = o; ~~~~~~~~~~ @@ -27,6 +30,10 @@ tests/cases/conformance/types/rest/objectRestNegative.ts(17,9): error TS2701: Th !!! error TS2462: A rest element must be last in a destructuring pattern } function generic(t: T) { + ~~ +!!! error TS7008: Member 'x' implicitly has an 'any' type. + ~ +!!! error TS7008: Member 'y' implicitly has an 'any' type. let { x, ...rest } = t; ~~~~ !!! error TS2700: Rest types may only be created from object types. @@ -37,4 +44,8 @@ tests/cases/conformance/types/rest/objectRestNegative.ts(17,9): error TS2701: Th ({a, ...rest.b + rest.b} = o); ~~~~~~~~~~~~~~~ !!! error TS2701: The target of an object rest assignment must be a variable or a property access. + + var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes; + ~~~~~~~~~~~~ +!!! error TS2339: Property 'anythingGoes' does not exist on type '{ [x: string]: any; }'. \ No newline at end of file diff --git a/tests/baselines/reference/objectRestNegative.js b/tests/baselines/reference/objectRestNegative.js index f8c5b72ada5d0..19559e865f293 100644 --- a/tests/baselines/reference/objectRestNegative.js +++ b/tests/baselines/reference/objectRestNegative.js @@ -16,6 +16,8 @@ function generic(t: T) { let rest: { b: string } ({a, ...rest.b + rest.b} = o); + +var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes; //// [objectRestNegative.js] @@ -23,7 +25,7 @@ var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; - if (typeof Object.getOwnPropertySymbols === "function") + if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]]; return t; @@ -42,3 +44,7 @@ function generic(t) { } var rest; (a = o.a, o, rest.b + rest.b = __rest(o, ["a"])); +var noContextualType = function (_a) { + var _b = _a.aNumber, aNumber = _b === void 0 ? 12 : _b, notEmptyObject = __rest(_a, ["aNumber"]); + return aNumber + notEmptyObject.anythingGoes; +}; diff --git a/tests/baselines/reference/objectRestParameter.js b/tests/baselines/reference/objectRestParameter.js index 87419bd06e909..14e84eddfce79 100644 --- a/tests/baselines/reference/objectRestParameter.js +++ b/tests/baselines/reference/objectRestParameter.js @@ -22,7 +22,7 @@ var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; - if (typeof Object.getOwnPropertySymbols === "function") + if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]]; return t; diff --git a/tests/baselines/reference/objectSpreadNegative.errors.txt b/tests/baselines/reference/objectSpreadNegative.errors.txt index dc6a356708f12..17f07bc06a296 100644 --- a/tests/baselines/reference/objectSpreadNegative.errors.txt +++ b/tests/baselines/reference/objectSpreadNegative.errors.txt @@ -7,20 +7,18 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(25,1): error TS2322 Property 's' is missing in type '{ b: boolean; }'. tests/cases/conformance/types/spread/objectSpreadNegative.ts(28,36): error TS2300: Duplicate identifier 'b'. tests/cases/conformance/types/spread/objectSpreadNegative.ts(28,53): error TS2300: Duplicate identifier 'b'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(32,20): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(33,24): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(34,19): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(35,19): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(37,20): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(39,19): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(44,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(48,12): error TS2339: Property 'b' does not exist on type '{}'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(54,9): error TS2339: Property 'm' does not exist on type '{ p: number; }'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(58,14): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(61,14): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(32,19): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(33,19): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(35,20): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(37,19): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(42,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(46,12): error TS2339: Property 'b' does not exist on type '{}'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(52,9): error TS2339: Property 'm' does not exist on type '{ p: number; }'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(56,14): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(59,14): error TS2698: Spread types may only be created from object types. -==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (17 errors) ==== +==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (15 errors) ==== let o = { a: 1, b: 'no' } /// private propagates @@ -66,13 +64,7 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(61,14): error TS269 !!! error TS2300: Duplicate identifier 'b'. let duplicatedSpread = { ...o, ...o } - // null, undefined and primitives are not allowed - let spreadNull = { ...null }; - ~~~~~~~ -!!! error TS2698: Spread types may only be created from object types. - let spreadUndefind = { ...undefined }; - ~~~~~~~~~~~~ -!!! error TS2698: Spread types may only be created from object types. + // primitives are not allowed let spreadNum = { ...12 }; ~~~~~ !!! error TS2698: Spread types may only be created from object types. diff --git a/tests/baselines/reference/objectSpreadNegative.js b/tests/baselines/reference/objectSpreadNegative.js index 6287f4559a79b..dff84355370e7 100644 --- a/tests/baselines/reference/objectSpreadNegative.js +++ b/tests/baselines/reference/objectSpreadNegative.js @@ -29,9 +29,7 @@ spread = b; // error, missing 's' let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' } let duplicatedSpread = { ...o, ...o } -// null, undefined and primitives are not allowed -let spreadNull = { ...null }; -let spreadUndefind = { ...undefined }; +// primitives are not allowed let spreadNum = { ...12 }; let spreadSum = { ...1 + 1 }; spreadSum.toFixed(); // error, no methods from number @@ -108,9 +106,7 @@ spread = b; // error, missing 's' // literal repeats are not allowed, but spread repeats are fine var duplicated = __assign({ b: 'bad' }, o, { b: 'bad' }, o2, { b: 'bad' }); var duplicatedSpread = __assign({}, o, o); -// null, undefined and primitives are not allowed -var spreadNull = __assign({}, null); -var spreadUndefind = __assign({}, undefined); +// primitives are not allowed var spreadNum = __assign({}, 12); var spreadSum = __assign({}, 1 + 1); spreadSum.toFixed(); // error, no methods from number diff --git a/tests/baselines/reference/restIntersection.js b/tests/baselines/reference/restIntersection.js new file mode 100644 index 0000000000000..d1f9aa3094cc4 --- /dev/null +++ b/tests/baselines/reference/restIntersection.js @@ -0,0 +1,20 @@ +//// [restIntersection.ts] +var intersection: { x: number, y: number } & { w: string, z: string }; + +var rest1: { y: number, w: string, z: string }; +var {x, ...rest1 } = intersection; + + +//// [restIntersection.js] +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +var intersection; +var rest1; +var x = intersection.x, rest1 = __rest(intersection, ["x"]); diff --git a/tests/baselines/reference/restIntersection.symbols b/tests/baselines/reference/restIntersection.symbols new file mode 100644 index 0000000000000..75f91d243e24e --- /dev/null +++ b/tests/baselines/reference/restIntersection.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/restIntersection.ts === +var intersection: { x: number, y: number } & { w: string, z: string }; +>intersection : Symbol(intersection, Decl(restIntersection.ts, 0, 3)) +>x : Symbol(x, Decl(restIntersection.ts, 0, 19)) +>y : Symbol(y, Decl(restIntersection.ts, 0, 30)) +>w : Symbol(w, Decl(restIntersection.ts, 0, 46)) +>z : Symbol(z, Decl(restIntersection.ts, 0, 57)) + +var rest1: { y: number, w: string, z: string }; +>rest1 : Symbol(rest1, Decl(restIntersection.ts, 2, 3), Decl(restIntersection.ts, 3, 7)) +>y : Symbol(y, Decl(restIntersection.ts, 2, 12)) +>w : Symbol(w, Decl(restIntersection.ts, 2, 23)) +>z : Symbol(z, Decl(restIntersection.ts, 2, 34)) + +var {x, ...rest1 } = intersection; +>x : Symbol(x, Decl(restIntersection.ts, 3, 5)) +>rest1 : Symbol(rest1, Decl(restIntersection.ts, 2, 3), Decl(restIntersection.ts, 3, 7)) +>intersection : Symbol(intersection, Decl(restIntersection.ts, 0, 3)) + diff --git a/tests/baselines/reference/restIntersection.types b/tests/baselines/reference/restIntersection.types new file mode 100644 index 0000000000000..5779349ba2986 --- /dev/null +++ b/tests/baselines/reference/restIntersection.types @@ -0,0 +1,19 @@ +=== tests/cases/compiler/restIntersection.ts === +var intersection: { x: number, y: number } & { w: string, z: string }; +>intersection : { x: number; y: number; } & { w: string; z: string; } +>x : number +>y : number +>w : string +>z : string + +var rest1: { y: number, w: string, z: string }; +>rest1 : { y: number; w: string; z: string; } +>y : number +>w : string +>z : string + +var {x, ...rest1 } = intersection; +>x : number +>rest1 : { y: number; w: string; z: string; } +>intersection : { x: number; y: number; } & { w: string; z: string; } + diff --git a/tests/baselines/reference/restInvalidArgumentType.errors.txt b/tests/baselines/reference/restInvalidArgumentType.errors.txt new file mode 100644 index 0000000000000..fff2c7b3563bc --- /dev/null +++ b/tests/baselines/reference/restInvalidArgumentType.errors.txt @@ -0,0 +1,104 @@ +tests/cases/compiler/restInvalidArgumentType.ts(31,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(33,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(35,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(36,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(38,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(41,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(42,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(44,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(45,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(47,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(48,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(55,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(56,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(58,13): error TS2700: Rest types may only be created from object types. + + +==== tests/cases/compiler/restInvalidArgumentType.ts (14 errors) ==== + enum E { v1, v2 }; + + function f(p1: T, p2: T[]) { + var t: T; + + var i: T["b"]; + var k: keyof T; + + var mapped_generic: {[P in keyof T]: T[P]}; + var mapped: {[P in "b"]: T[P]}; + + var union_generic: T | { a: number }; + var union_primitive: { a: number } | number; + + var intersection_generic: T & { a: number }; + var intersection_premitive: { a: number } | string; + + var num: number; + var str: number; + + var u: undefined; + var n: null; + + var a: any; + + var literal_string: "string"; + var literal_number: 42; + + var e: E; + + var {...r1} = p1; // Error, generic type paramterre + ~~ +!!! error TS2700: Rest types may only be created from object types. + var {...r2} = p2; // OK + var {...r3} = t; // Error, generic type paramter + ~~ +!!! error TS2700: Rest types may only be created from object types. + + var {...r4} = i; // Error, index access + ~~ +!!! error TS2700: Rest types may only be created from object types. + var {...r5} = k; // Error, index + ~~ +!!! error TS2700: Rest types may only be created from object types. + + var {...r6} = mapped_generic; // Error, generic mapped object type + ~~ +!!! error TS2700: Rest types may only be created from object types. + var {...r7} = mapped; // OK, non-generic mapped type + + var {...r8} = union_generic; // Error, union with generic type parameter + ~~ +!!! error TS2700: Rest types may only be created from object types. + var {...r9} = union_primitive; // Error, union with generic type parameter + ~~ +!!! error TS2700: Rest types may only be created from object types. + + var {...r10} = intersection_generic; // Error, intersection with generic type parameter + ~~~ +!!! error TS2700: Rest types may only be created from object types. + var {...r11} = intersection_premitive; // Error, intersection with generic type parameter + ~~~ +!!! error TS2700: Rest types may only be created from object types. + + var {...r12} = num; // Error + ~~~ +!!! error TS2700: Rest types may only be created from object types. + var {...r13} = str; // Error + ~~~ +!!! error TS2700: Rest types may only be created from object types. + + var {...r14} = u; // OK + var {...r15} = n; // OK + + var {...r16} = a; // OK + + var {...r17} = literal_string; // Error + ~~~ +!!! error TS2700: Rest types may only be created from object types. + var {...r18} = literal_number; // Error + ~~~ +!!! error TS2700: Rest types may only be created from object types. + + var {...r19} = e; // Error, enum + ~~~ +!!! error TS2700: Rest types may only be created from object types. + } \ No newline at end of file diff --git a/tests/baselines/reference/restInvalidArgumentType.js b/tests/baselines/reference/restInvalidArgumentType.js new file mode 100644 index 0000000000000..48e4e11e8051d --- /dev/null +++ b/tests/baselines/reference/restInvalidArgumentType.js @@ -0,0 +1,115 @@ +//// [restInvalidArgumentType.ts] +enum E { v1, v2 }; + +function f(p1: T, p2: T[]) { + var t: T; + + var i: T["b"]; + var k: keyof T; + + var mapped_generic: {[P in keyof T]: T[P]}; + var mapped: {[P in "b"]: T[P]}; + + var union_generic: T | { a: number }; + var union_primitive: { a: number } | number; + + var intersection_generic: T & { a: number }; + var intersection_premitive: { a: number } | string; + + var num: number; + var str: number; + + var u: undefined; + var n: null; + + var a: any; + + var literal_string: "string"; + var literal_number: 42; + + var e: E; + + var {...r1} = p1; // Error, generic type paramterre + var {...r2} = p2; // OK + var {...r3} = t; // Error, generic type paramter + + var {...r4} = i; // Error, index access + var {...r5} = k; // Error, index + + var {...r6} = mapped_generic; // Error, generic mapped object type + var {...r7} = mapped; // OK, non-generic mapped type + + var {...r8} = union_generic; // Error, union with generic type parameter + var {...r9} = union_primitive; // Error, union with generic type parameter + + var {...r10} = intersection_generic; // Error, intersection with generic type parameter + var {...r11} = intersection_premitive; // Error, intersection with generic type parameter + + var {...r12} = num; // Error + var {...r13} = str; // Error + + var {...r14} = u; // OK + var {...r15} = n; // OK + + var {...r16} = a; // OK + + var {...r17} = literal_string; // Error + var {...r18} = literal_number; // Error + + var {...r19} = e; // Error, enum +} + +//// [restInvalidArgumentType.js] +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +var E; +(function (E) { + E[E["v1"] = 0] = "v1"; + E[E["v2"] = 1] = "v2"; +})(E || (E = {})); +; +function f(p1, p2) { + var t; + var i; + var k; + var mapped_generic; + var mapped; + var union_generic; + var union_primitive; + var intersection_generic; + var intersection_premitive; + var num; + var str; + var u; + var n; + var a; + var literal_string; + var literal_number; + var e; + var r1 = __rest(p1, []); // Error, generic type paramterre + var r2 = __rest(p2, []); // OK + var r3 = __rest(t, []); // Error, generic type paramter + var r4 = __rest(i, []); // Error, index access + var r5 = __rest(k, []); // Error, index + var r6 = __rest(mapped_generic, []); // Error, generic mapped object type + var r7 = __rest(mapped, []); // OK, non-generic mapped type + var r8 = __rest(union_generic, []); // Error, union with generic type parameter + var r9 = __rest(union_primitive, []); // Error, union with generic type parameter + var r10 = __rest(intersection_generic, []); // Error, intersection with generic type parameter + var r11 = __rest(intersection_premitive, []); // Error, intersection with generic type parameter + var r12 = __rest(num, []); // Error + var r13 = __rest(str, []); // Error + var r14 = __rest(u, []); // OK + var r15 = __rest(n, []); // OK + var r16 = __rest(a, []); // OK + var r17 = __rest(literal_string, []); // Error + var r18 = __rest(literal_number, []); // Error + var r19 = __rest(e, []); // Error, enum +} diff --git a/tests/baselines/reference/restUnion.js b/tests/baselines/reference/restUnion.js new file mode 100644 index 0000000000000..09a6243d2a957 --- /dev/null +++ b/tests/baselines/reference/restUnion.js @@ -0,0 +1,36 @@ +//// [restUnion.ts] +var union: { a: number, c: boolean } | { a: string, b: string }; + +var rest1: { c: boolean } | { b: string }; +var {a, ...rest1 } = union; + + +var undefinedUnion: { n: number } | undefined; +var rest2: {}; +var {n, ...rest2 } = undefinedUnion; + + +var nullUnion: { n: number } | null; +var rest3: {}; +var {n, ...rest3 } = nullUnion; + + +//// [restUnion.js] +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +var union; +var rest1; +var a = union.a, rest1 = __rest(union, ["a"]); +var undefinedUnion; +var rest2; +var n = undefinedUnion.n, rest2 = __rest(undefinedUnion, ["n"]); +var nullUnion; +var rest3; +var n = nullUnion.n, rest3 = __rest(nullUnion, ["n"]); diff --git a/tests/baselines/reference/restUnion.symbols b/tests/baselines/reference/restUnion.symbols new file mode 100644 index 0000000000000..660c85badb4e7 --- /dev/null +++ b/tests/baselines/reference/restUnion.symbols @@ -0,0 +1,44 @@ +=== tests/cases/compiler/restUnion.ts === +var union: { a: number, c: boolean } | { a: string, b: string }; +>union : Symbol(union, Decl(restUnion.ts, 0, 3)) +>a : Symbol(a, Decl(restUnion.ts, 0, 12)) +>c : Symbol(c, Decl(restUnion.ts, 0, 23)) +>a : Symbol(a, Decl(restUnion.ts, 0, 40)) +>b : Symbol(b, Decl(restUnion.ts, 0, 51)) + +var rest1: { c: boolean } | { b: string }; +>rest1 : Symbol(rest1, Decl(restUnion.ts, 2, 3), Decl(restUnion.ts, 3, 7)) +>c : Symbol(c, Decl(restUnion.ts, 2, 12)) +>b : Symbol(b, Decl(restUnion.ts, 2, 29)) + +var {a, ...rest1 } = union; +>a : Symbol(a, Decl(restUnion.ts, 3, 5)) +>rest1 : Symbol(rest1, Decl(restUnion.ts, 2, 3), Decl(restUnion.ts, 3, 7)) +>union : Symbol(union, Decl(restUnion.ts, 0, 3)) + + +var undefinedUnion: { n: number } | undefined; +>undefinedUnion : Symbol(undefinedUnion, Decl(restUnion.ts, 6, 3)) +>n : Symbol(n, Decl(restUnion.ts, 6, 21)) + +var rest2: {}; +>rest2 : Symbol(rest2, Decl(restUnion.ts, 7, 3), Decl(restUnion.ts, 8, 7)) + +var {n, ...rest2 } = undefinedUnion; +>n : Symbol(n, Decl(restUnion.ts, 8, 5), Decl(restUnion.ts, 13, 5)) +>rest2 : Symbol(rest2, Decl(restUnion.ts, 7, 3), Decl(restUnion.ts, 8, 7)) +>undefinedUnion : Symbol(undefinedUnion, Decl(restUnion.ts, 6, 3)) + + +var nullUnion: { n: number } | null; +>nullUnion : Symbol(nullUnion, Decl(restUnion.ts, 11, 3)) +>n : Symbol(n, Decl(restUnion.ts, 11, 16)) + +var rest3: {}; +>rest3 : Symbol(rest3, Decl(restUnion.ts, 12, 3), Decl(restUnion.ts, 13, 7)) + +var {n, ...rest3 } = nullUnion; +>n : Symbol(n, Decl(restUnion.ts, 8, 5), Decl(restUnion.ts, 13, 5)) +>rest3 : Symbol(rest3, Decl(restUnion.ts, 12, 3), Decl(restUnion.ts, 13, 7)) +>nullUnion : Symbol(nullUnion, Decl(restUnion.ts, 11, 3)) + diff --git a/tests/baselines/reference/restUnion.types b/tests/baselines/reference/restUnion.types new file mode 100644 index 0000000000000..9837466684b26 --- /dev/null +++ b/tests/baselines/reference/restUnion.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/restUnion.ts === +var union: { a: number, c: boolean } | { a: string, b: string }; +>union : { a: number; c: boolean; } | { a: string; b: string; } +>a : number +>c : boolean +>a : string +>b : string + +var rest1: { c: boolean } | { b: string }; +>rest1 : { c: boolean; } | { b: string; } +>c : boolean +>b : string + +var {a, ...rest1 } = union; +>a : string | number +>rest1 : { c: boolean; } | { b: string; } +>union : { a: number; c: boolean; } | { a: string; b: string; } + + +var undefinedUnion: { n: number } | undefined; +>undefinedUnion : { n: number; } +>n : number + +var rest2: {}; +>rest2 : {} + +var {n, ...rest2 } = undefinedUnion; +>n : number +>rest2 : {} +>undefinedUnion : { n: number; } + + +var nullUnion: { n: number } | null; +>nullUnion : { n: number; } +>n : number +>null : null + +var rest3: {}; +>rest3 : {} + +var {n, ...rest3 } = nullUnion; +>n : number +>rest3 : {} +>nullUnion : { n: number; } + diff --git a/tests/baselines/reference/restUnion2.js b/tests/baselines/reference/restUnion2.js new file mode 100644 index 0000000000000..44a0acfbcf825 --- /dev/null +++ b/tests/baselines/reference/restUnion2.js @@ -0,0 +1,38 @@ +//// [restUnion2.ts] + +declare const undefinedUnion: { n: number } | undefined; +var rest2: { n: number }; +var {...rest2 } = undefinedUnion; + + +declare const nullUnion: { n: number } | null; +var rest3: { n: number }; +var {...rest3 } = nullUnion; + + +declare const nullAndUndefinedUnion: null | undefined; +var rest4: { }; +var {...rest4 } = nullAndUndefinedUnion; + +declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined | null; +var rest5: { n: number, s: string }; +var {...rest5 } = unionWithIntersection; + +//// [restUnion2.js] +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +var rest2; +var rest2 = __rest(undefinedUnion, []); +var rest3; +var rest3 = __rest(nullUnion, []); +var rest4; +var rest4 = __rest(nullAndUndefinedUnion, []); +var rest5; +var rest5 = __rest(unionWithIntersection, []); diff --git a/tests/baselines/reference/restUnion2.symbols b/tests/baselines/reference/restUnion2.symbols new file mode 100644 index 0000000000000..20a113a23b498 --- /dev/null +++ b/tests/baselines/reference/restUnion2.symbols @@ -0,0 +1,52 @@ +=== tests/cases/compiler/restUnion2.ts === + +declare const undefinedUnion: { n: number } | undefined; +>undefinedUnion : Symbol(undefinedUnion, Decl(restUnion2.ts, 1, 13)) +>n : Symbol(n, Decl(restUnion2.ts, 1, 31)) + +var rest2: { n: number }; +>rest2 : Symbol(rest2, Decl(restUnion2.ts, 2, 3), Decl(restUnion2.ts, 3, 5)) +>n : Symbol(n, Decl(restUnion2.ts, 2, 12)) + +var {...rest2 } = undefinedUnion; +>rest2 : Symbol(rest2, Decl(restUnion2.ts, 2, 3), Decl(restUnion2.ts, 3, 5)) +>undefinedUnion : Symbol(undefinedUnion, Decl(restUnion2.ts, 1, 13)) + + +declare const nullUnion: { n: number } | null; +>nullUnion : Symbol(nullUnion, Decl(restUnion2.ts, 6, 13)) +>n : Symbol(n, Decl(restUnion2.ts, 6, 26)) + +var rest3: { n: number }; +>rest3 : Symbol(rest3, Decl(restUnion2.ts, 7, 3), Decl(restUnion2.ts, 8, 5)) +>n : Symbol(n, Decl(restUnion2.ts, 7, 12)) + +var {...rest3 } = nullUnion; +>rest3 : Symbol(rest3, Decl(restUnion2.ts, 7, 3), Decl(restUnion2.ts, 8, 5)) +>nullUnion : Symbol(nullUnion, Decl(restUnion2.ts, 6, 13)) + + +declare const nullAndUndefinedUnion: null | undefined; +>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(restUnion2.ts, 11, 13)) + +var rest4: { }; +>rest4 : Symbol(rest4, Decl(restUnion2.ts, 12, 3), Decl(restUnion2.ts, 13, 5)) + +var {...rest4 } = nullAndUndefinedUnion; +>rest4 : Symbol(rest4, Decl(restUnion2.ts, 12, 3), Decl(restUnion2.ts, 13, 5)) +>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(restUnion2.ts, 11, 13)) + +declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined | null; +>unionWithIntersection : Symbol(unionWithIntersection, Decl(restUnion2.ts, 15, 13)) +>n : Symbol(n, Decl(restUnion2.ts, 15, 39)) +>s : Symbol(s, Decl(restUnion2.ts, 15, 55)) + +var rest5: { n: number, s: string }; +>rest5 : Symbol(rest5, Decl(restUnion2.ts, 16, 3), Decl(restUnion2.ts, 17, 5)) +>n : Symbol(n, Decl(restUnion2.ts, 16, 12)) +>s : Symbol(s, Decl(restUnion2.ts, 16, 23)) + +var {...rest5 } = unionWithIntersection; +>rest5 : Symbol(rest5, Decl(restUnion2.ts, 16, 3), Decl(restUnion2.ts, 17, 5)) +>unionWithIntersection : Symbol(unionWithIntersection, Decl(restUnion2.ts, 15, 13)) + diff --git a/tests/baselines/reference/restUnion2.types b/tests/baselines/reference/restUnion2.types new file mode 100644 index 0000000000000..81b768777fd17 --- /dev/null +++ b/tests/baselines/reference/restUnion2.types @@ -0,0 +1,55 @@ +=== tests/cases/compiler/restUnion2.ts === + +declare const undefinedUnion: { n: number } | undefined; +>undefinedUnion : { n: number; } | undefined +>n : number + +var rest2: { n: number }; +>rest2 : { n: number; } +>n : number + +var {...rest2 } = undefinedUnion; +>rest2 : { n: number; } +>undefinedUnion : { n: number; } | undefined + + +declare const nullUnion: { n: number } | null; +>nullUnion : { n: number; } | null +>n : number +>null : null + +var rest3: { n: number }; +>rest3 : { n: number; } +>n : number + +var {...rest3 } = nullUnion; +>rest3 : { n: number; } +>nullUnion : { n: number; } | null + + +declare const nullAndUndefinedUnion: null | undefined; +>nullAndUndefinedUnion : null | undefined +>null : null + +var rest4: { }; +>rest4 : {} + +var {...rest4 } = nullAndUndefinedUnion; +>rest4 : {} +>nullAndUndefinedUnion : null | undefined + +declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined | null; +>unionWithIntersection : ({ n: number; } & { s: string; } & undefined) | null +>n : number +>s : string +>null : null + +var rest5: { n: number, s: string }; +>rest5 : { n: number; s: string; } +>n : number +>s : string + +var {...rest5 } = unionWithIntersection; +>rest5 : { n: number; s: string; } +>unionWithIntersection : ({ n: number; } & { s: string; } & undefined) | null + diff --git a/tests/baselines/reference/spreadIntersection.js b/tests/baselines/reference/spreadIntersection.js new file mode 100644 index 0000000000000..b3fa9f0c2fbc1 --- /dev/null +++ b/tests/baselines/reference/spreadIntersection.js @@ -0,0 +1,23 @@ +//// [spreadIntersection.ts] +var intersection: { a: number } & { b: string }; + +var o1: { a: number, b: string }; +var o1 = { ...intersection }; + +var o2: { a: number, b: string, c: boolean }; +var o2 = { ...intersection, c: false }; + +//// [spreadIntersection.js] +var __assign = (this && this.__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; +}; +var intersection; +var o1; +var o1 = __assign({}, intersection); +var o2; +var o2 = __assign({}, intersection, { c: false }); diff --git a/tests/baselines/reference/spreadIntersection.symbols b/tests/baselines/reference/spreadIntersection.symbols new file mode 100644 index 0000000000000..1f6b3c12de16c --- /dev/null +++ b/tests/baselines/reference/spreadIntersection.symbols @@ -0,0 +1,26 @@ +=== tests/cases/compiler/spreadIntersection.ts === +var intersection: { a: number } & { b: string }; +>intersection : Symbol(intersection, Decl(spreadIntersection.ts, 0, 3)) +>a : Symbol(a, Decl(spreadIntersection.ts, 0, 19)) +>b : Symbol(b, Decl(spreadIntersection.ts, 0, 35)) + +var o1: { a: number, b: string }; +>o1 : Symbol(o1, Decl(spreadIntersection.ts, 2, 3), Decl(spreadIntersection.ts, 3, 3)) +>a : Symbol(a, Decl(spreadIntersection.ts, 2, 9)) +>b : Symbol(b, Decl(spreadIntersection.ts, 2, 20)) + +var o1 = { ...intersection }; +>o1 : Symbol(o1, Decl(spreadIntersection.ts, 2, 3), Decl(spreadIntersection.ts, 3, 3)) +>intersection : Symbol(intersection, Decl(spreadIntersection.ts, 0, 3)) + +var o2: { a: number, b: string, c: boolean }; +>o2 : Symbol(o2, Decl(spreadIntersection.ts, 5, 3), Decl(spreadIntersection.ts, 6, 3)) +>a : Symbol(a, Decl(spreadIntersection.ts, 5, 9)) +>b : Symbol(b, Decl(spreadIntersection.ts, 5, 20)) +>c : Symbol(c, Decl(spreadIntersection.ts, 5, 31)) + +var o2 = { ...intersection, c: false }; +>o2 : Symbol(o2, Decl(spreadIntersection.ts, 5, 3), Decl(spreadIntersection.ts, 6, 3)) +>intersection : Symbol(intersection, Decl(spreadIntersection.ts, 0, 3)) +>c : Symbol(c, Decl(spreadIntersection.ts, 6, 27)) + diff --git a/tests/baselines/reference/spreadIntersection.types b/tests/baselines/reference/spreadIntersection.types new file mode 100644 index 0000000000000..c3c6b99adeede --- /dev/null +++ b/tests/baselines/reference/spreadIntersection.types @@ -0,0 +1,29 @@ +=== tests/cases/compiler/spreadIntersection.ts === +var intersection: { a: number } & { b: string }; +>intersection : { a: number; } & { b: string; } +>a : number +>b : string + +var o1: { a: number, b: string }; +>o1 : { a: number; b: string; } +>a : number +>b : string + +var o1 = { ...intersection }; +>o1 : { a: number; b: string; } +>{ ...intersection } : { a: number; b: string; } +>intersection : { a: number; } & { b: string; } + +var o2: { a: number, b: string, c: boolean }; +>o2 : { a: number; b: string; c: boolean; } +>a : number +>b : string +>c : boolean + +var o2 = { ...intersection, c: false }; +>o2 : { a: number; b: string; c: boolean; } +>{ ...intersection, c: false } : { c: boolean; a: number; b: string; } +>intersection : { a: number; } & { b: string; } +>c : boolean +>false : false + diff --git a/tests/baselines/reference/spreadInvalidArgumentType.errors.txt b/tests/baselines/reference/spreadInvalidArgumentType.errors.txt new file mode 100644 index 0000000000000..5088390f9eea9 --- /dev/null +++ b/tests/baselines/reference/spreadInvalidArgumentType.errors.txt @@ -0,0 +1,104 @@ +tests/cases/compiler/spreadInvalidArgumentType.ts(31,16): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(33,16): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(35,16): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(36,16): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(38,16): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(41,16): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(42,16): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(44,17): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(45,17): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(47,17): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(48,17): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(55,17): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(56,17): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(58,17): error TS2698: Spread types may only be created from object types. + + +==== tests/cases/compiler/spreadInvalidArgumentType.ts (14 errors) ==== + enum E { v1, v2 }; + + function f(p1: T, p2: T[]) { + var t: T; + + var i: T["b"]; + var k: keyof T; + + var mapped_generic: {[P in keyof T]: T[P]}; + var mapped: {[P in "b"]: T[P]}; + + var union_generic: T | { a: number }; + var union_primitive: { a: number } | number; + + var intersection_generic: T & { a: number }; + var intersection_premitive: { a: number } | string; + + var num: number; + var str: number; + + var u: undefined; + var n: null; + + var a: any; + + var literal_string: "string"; + var literal_number: 42; + + var e: E; + + var o1 = { ...p1 }; // Error, generic type paramterre + ~~~~~ +!!! error TS2698: Spread types may only be created from object types. + var o2 = { ...p2 }; // OK + var o3 = { ...t }; // Error, generic type paramter + ~~~~ +!!! error TS2698: Spread types may only be created from object types. + + var o4 = { ...i }; // Error, index access + ~~~~ +!!! error TS2698: Spread types may only be created from object types. + var o5 = { ...k }; // Error, index + ~~~~ +!!! error TS2698: Spread types may only be created from object types. + + var o6 = { ...mapped_generic }; // Error, generic mapped object type + ~~~~~~~~~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + var o7 = { ...mapped }; // OK, non-generic mapped type + + var o8 = { ...union_generic }; // Error, union with generic type parameter + ~~~~~~~~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + var o9 = { ...union_primitive }; // Error, union with generic type parameter + ~~~~~~~~~~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + + var o10 = { ...intersection_generic }; // Error, intersection with generic type parameter + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + var o11 = { ...intersection_premitive }; // Error, intersection with generic type parameter + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + + var o12 = { ...num }; // Error + ~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + var o13 = { ...str }; // Error + ~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + + var o14 = { ...u }; // OK + var o15 = { ...n }; // OK + + var o16 = { ...a }; // OK + + var o17 = { ...literal_string }; // Error + ~~~~~~~~~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + var o18 = { ...literal_number }; // Error + ~~~~~~~~~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + + var o19 = { ...e }; // Error, enum + ~~~~ +!!! error TS2698: Spread types may only be created from object types. + } \ No newline at end of file diff --git a/tests/baselines/reference/spreadInvalidArgumentType.js b/tests/baselines/reference/spreadInvalidArgumentType.js new file mode 100644 index 0000000000000..26f958f224da3 --- /dev/null +++ b/tests/baselines/reference/spreadInvalidArgumentType.js @@ -0,0 +1,114 @@ +//// [spreadInvalidArgumentType.ts] +enum E { v1, v2 }; + +function f(p1: T, p2: T[]) { + var t: T; + + var i: T["b"]; + var k: keyof T; + + var mapped_generic: {[P in keyof T]: T[P]}; + var mapped: {[P in "b"]: T[P]}; + + var union_generic: T | { a: number }; + var union_primitive: { a: number } | number; + + var intersection_generic: T & { a: number }; + var intersection_premitive: { a: number } | string; + + var num: number; + var str: number; + + var u: undefined; + var n: null; + + var a: any; + + var literal_string: "string"; + var literal_number: 42; + + var e: E; + + var o1 = { ...p1 }; // Error, generic type paramterre + var o2 = { ...p2 }; // OK + var o3 = { ...t }; // Error, generic type paramter + + var o4 = { ...i }; // Error, index access + var o5 = { ...k }; // Error, index + + var o6 = { ...mapped_generic }; // Error, generic mapped object type + var o7 = { ...mapped }; // OK, non-generic mapped type + + var o8 = { ...union_generic }; // Error, union with generic type parameter + var o9 = { ...union_primitive }; // Error, union with generic type parameter + + var o10 = { ...intersection_generic }; // Error, intersection with generic type parameter + var o11 = { ...intersection_premitive }; // Error, intersection with generic type parameter + + var o12 = { ...num }; // Error + var o13 = { ...str }; // Error + + var o14 = { ...u }; // OK + var o15 = { ...n }; // OK + + var o16 = { ...a }; // OK + + var o17 = { ...literal_string }; // Error + var o18 = { ...literal_number }; // Error + + var o19 = { ...e }; // Error, enum +} + +//// [spreadInvalidArgumentType.js] +var __assign = (this && this.__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; +}; +var E; +(function (E) { + E[E["v1"] = 0] = "v1"; + E[E["v2"] = 1] = "v2"; +})(E || (E = {})); +; +function f(p1, p2) { + var t; + var i; + var k; + var mapped_generic; + var mapped; + var union_generic; + var union_primitive; + var intersection_generic; + var intersection_premitive; + var num; + var str; + var u; + var n; + var a; + var literal_string; + var literal_number; + var e; + var o1 = __assign({}, p1); // Error, generic type paramterre + var o2 = __assign({}, p2); // OK + var o3 = __assign({}, t); // Error, generic type paramter + var o4 = __assign({}, i); // Error, index access + var o5 = __assign({}, k); // Error, index + var o6 = __assign({}, mapped_generic); // Error, generic mapped object type + var o7 = __assign({}, mapped); // OK, non-generic mapped type + var o8 = __assign({}, union_generic); // Error, union with generic type parameter + var o9 = __assign({}, union_primitive); // Error, union with generic type parameter + var o10 = __assign({}, intersection_generic); // Error, intersection with generic type parameter + var o11 = __assign({}, intersection_premitive); // Error, intersection with generic type parameter + var o12 = __assign({}, num); // Error + var o13 = __assign({}, str); // Error + var o14 = __assign({}, u); // OK + var o15 = __assign({}, n); // OK + var o16 = __assign({}, a); // OK + var o17 = __assign({}, literal_string); // Error + var o18 = __assign({}, literal_number); // Error + var o19 = __assign({}, e); // Error, enum +} diff --git a/tests/baselines/reference/spreadUnion.js b/tests/baselines/reference/spreadUnion.js new file mode 100644 index 0000000000000..2691a3acdcc22 --- /dev/null +++ b/tests/baselines/reference/spreadUnion.js @@ -0,0 +1,28 @@ +//// [spreadUnion.ts] +var union: { a: number } | { b: string }; + +var o3: { a: number } | { b: string }; +var o3 = { ...union }; + +var o4: { a: boolean } | { b: string , a: boolean}; +var o4 = { ...union, a: false }; + +var o5: { a: number } | { b: string } | { a: number, b: string }; +var o5 = { ...union, ...union }; + +//// [spreadUnion.js] +var __assign = (this && this.__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; +}; +var union; +var o3; +var o3 = __assign({}, union); +var o4; +var o4 = __assign({}, union, { a: false }); +var o5; +var o5 = __assign({}, union, union); diff --git a/tests/baselines/reference/spreadUnion.symbols b/tests/baselines/reference/spreadUnion.symbols new file mode 100644 index 0000000000000..40a63d56d49c8 --- /dev/null +++ b/tests/baselines/reference/spreadUnion.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/spreadUnion.ts === +var union: { a: number } | { b: string }; +>union : Symbol(union, Decl(spreadUnion.ts, 0, 3)) +>a : Symbol(a, Decl(spreadUnion.ts, 0, 12)) +>b : Symbol(b, Decl(spreadUnion.ts, 0, 28)) + +var o3: { a: number } | { b: string }; +>o3 : Symbol(o3, Decl(spreadUnion.ts, 2, 3), Decl(spreadUnion.ts, 3, 3)) +>a : Symbol(a, Decl(spreadUnion.ts, 2, 9)) +>b : Symbol(b, Decl(spreadUnion.ts, 2, 25)) + +var o3 = { ...union }; +>o3 : Symbol(o3, Decl(spreadUnion.ts, 2, 3), Decl(spreadUnion.ts, 3, 3)) +>union : Symbol(union, Decl(spreadUnion.ts, 0, 3)) + +var o4: { a: boolean } | { b: string , a: boolean}; +>o4 : Symbol(o4, Decl(spreadUnion.ts, 5, 3), Decl(spreadUnion.ts, 6, 3)) +>a : Symbol(a, Decl(spreadUnion.ts, 5, 9)) +>b : Symbol(b, Decl(spreadUnion.ts, 5, 26)) +>a : Symbol(a, Decl(spreadUnion.ts, 5, 38)) + +var o4 = { ...union, a: false }; +>o4 : Symbol(o4, Decl(spreadUnion.ts, 5, 3), Decl(spreadUnion.ts, 6, 3)) +>union : Symbol(union, Decl(spreadUnion.ts, 0, 3)) +>a : Symbol(a, Decl(spreadUnion.ts, 6, 21)) + +var o5: { a: number } | { b: string } | { a: number, b: string }; +>o5 : Symbol(o5, Decl(spreadUnion.ts, 8, 3), Decl(spreadUnion.ts, 9, 3)) +>a : Symbol(a, Decl(spreadUnion.ts, 8, 9)) +>b : Symbol(b, Decl(spreadUnion.ts, 8, 25)) +>a : Symbol(a, Decl(spreadUnion.ts, 8, 41)) +>b : Symbol(b, Decl(spreadUnion.ts, 8, 52)) + +var o5 = { ...union, ...union }; +>o5 : Symbol(o5, Decl(spreadUnion.ts, 8, 3), Decl(spreadUnion.ts, 9, 3)) +>union : Symbol(union, Decl(spreadUnion.ts, 0, 3)) +>union : Symbol(union, Decl(spreadUnion.ts, 0, 3)) + diff --git a/tests/baselines/reference/spreadUnion.types b/tests/baselines/reference/spreadUnion.types new file mode 100644 index 0000000000000..9e5ac1cffd555 --- /dev/null +++ b/tests/baselines/reference/spreadUnion.types @@ -0,0 +1,42 @@ +=== tests/cases/compiler/spreadUnion.ts === +var union: { a: number } | { b: string }; +>union : { a: number; } | { b: string; } +>a : number +>b : string + +var o3: { a: number } | { b: string }; +>o3 : { a: number; } | { b: string; } +>a : number +>b : string + +var o3 = { ...union }; +>o3 : { a: number; } | { b: string; } +>{ ...union } : { a: number; } | { b: string; } +>union : { a: number; } | { b: string; } + +var o4: { a: boolean } | { b: string , a: boolean}; +>o4 : { a: boolean; } | { b: string; a: boolean; } +>a : boolean +>b : string +>a : boolean + +var o4 = { ...union, a: false }; +>o4 : { a: boolean; } | { b: string; a: boolean; } +>{ ...union, a: false } : { a: boolean; } | { a: boolean; b: string; } +>union : { a: number; } | { b: string; } +>a : boolean +>false : false + +var o5: { a: number } | { b: string } | { a: number, b: string }; +>o5 : { a: number; } | { b: string; } | { a: number; b: string; } +>a : number +>b : string +>a : number +>b : string + +var o5 = { ...union, ...union }; +>o5 : { a: number; } | { b: string; } | { a: number; b: string; } +>{ ...union, ...union } : { a: number; } | { b: string; a: number; } | { a: number; b: string; } | { b: string; } +>union : { a: number; } | { b: string; } +>union : { a: number; } | { b: string; } + diff --git a/tests/baselines/reference/spreadUnion2.js b/tests/baselines/reference/spreadUnion2.js new file mode 100644 index 0000000000000..6c7527af9dd26 --- /dev/null +++ b/tests/baselines/reference/spreadUnion2.js @@ -0,0 +1,49 @@ +//// [spreadUnion2.ts] + +declare const undefinedUnion: { a: number } | undefined; +declare const nullUnion: { b: number } | null; +declare const nullAndUndefinedUnion: null | undefined; + +var o1: { a: number }; +var o1 = { ...undefinedUnion }; + +var o2: { b: number }; +var o2 = { ...nullUnion }; + +var o3: { a: number, b: number }; +var o3 = { ...undefinedUnion, ...nullUnion }; +var o3 = { ...nullUnion, ...undefinedUnion }; + +var o4: { a: number }; +var o4 = { ...undefinedUnion, ...undefinedUnion }; + +var o5: { b: number }; +var o5 = { ...nullUnion, ...nullUnion }; + +var o6: { }; +var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; +var o6 = { ...nullAndUndefinedUnion }; + +//// [spreadUnion2.js] +var __assign = (this && this.__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; +}; +var o1; +var o1 = __assign({}, undefinedUnion); +var o2; +var o2 = __assign({}, nullUnion); +var o3; +var o3 = __assign({}, undefinedUnion, nullUnion); +var o3 = __assign({}, nullUnion, undefinedUnion); +var o4; +var o4 = __assign({}, undefinedUnion, undefinedUnion); +var o5; +var o5 = __assign({}, nullUnion, nullUnion); +var o6; +var o6 = __assign({}, nullAndUndefinedUnion, nullAndUndefinedUnion); +var o6 = __assign({}, nullAndUndefinedUnion); diff --git a/tests/baselines/reference/spreadUnion2.symbols b/tests/baselines/reference/spreadUnion2.symbols new file mode 100644 index 0000000000000..cc2c194f2a65f --- /dev/null +++ b/tests/baselines/reference/spreadUnion2.symbols @@ -0,0 +1,74 @@ +=== tests/cases/compiler/spreadUnion2.ts === + +declare const undefinedUnion: { a: number } | undefined; +>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13)) +>a : Symbol(a, Decl(spreadUnion2.ts, 1, 31)) + +declare const nullUnion: { b: number } | null; +>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13)) +>b : Symbol(b, Decl(spreadUnion2.ts, 2, 26)) + +declare const nullAndUndefinedUnion: null | undefined; +>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 3, 13)) + +var o1: { a: number }; +>o1 : Symbol(o1, Decl(spreadUnion2.ts, 5, 3), Decl(spreadUnion2.ts, 6, 3)) +>a : Symbol(a, Decl(spreadUnion2.ts, 5, 9)) + +var o1 = { ...undefinedUnion }; +>o1 : Symbol(o1, Decl(spreadUnion2.ts, 5, 3), Decl(spreadUnion2.ts, 6, 3)) +>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13)) + +var o2: { b: number }; +>o2 : Symbol(o2, Decl(spreadUnion2.ts, 8, 3), Decl(spreadUnion2.ts, 9, 3)) +>b : Symbol(b, Decl(spreadUnion2.ts, 8, 9)) + +var o2 = { ...nullUnion }; +>o2 : Symbol(o2, Decl(spreadUnion2.ts, 8, 3), Decl(spreadUnion2.ts, 9, 3)) +>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13)) + +var o3: { a: number, b: number }; +>o3 : Symbol(o3, Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3), Decl(spreadUnion2.ts, 13, 3)) +>a : Symbol(a, Decl(spreadUnion2.ts, 11, 9)) +>b : Symbol(b, Decl(spreadUnion2.ts, 11, 20)) + +var o3 = { ...undefinedUnion, ...nullUnion }; +>o3 : Symbol(o3, Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3), Decl(spreadUnion2.ts, 13, 3)) +>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13)) +>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13)) + +var o3 = { ...nullUnion, ...undefinedUnion }; +>o3 : Symbol(o3, Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3), Decl(spreadUnion2.ts, 13, 3)) +>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13)) +>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13)) + +var o4: { a: number }; +>o4 : Symbol(o4, Decl(spreadUnion2.ts, 15, 3), Decl(spreadUnion2.ts, 16, 3)) +>a : Symbol(a, Decl(spreadUnion2.ts, 15, 9)) + +var o4 = { ...undefinedUnion, ...undefinedUnion }; +>o4 : Symbol(o4, Decl(spreadUnion2.ts, 15, 3), Decl(spreadUnion2.ts, 16, 3)) +>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13)) +>undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 1, 13)) + +var o5: { b: number }; +>o5 : Symbol(o5, Decl(spreadUnion2.ts, 18, 3), Decl(spreadUnion2.ts, 19, 3)) +>b : Symbol(b, Decl(spreadUnion2.ts, 18, 9)) + +var o5 = { ...nullUnion, ...nullUnion }; +>o5 : Symbol(o5, Decl(spreadUnion2.ts, 18, 3), Decl(spreadUnion2.ts, 19, 3)) +>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13)) +>nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 2, 13)) + +var o6: { }; +>o6 : Symbol(o6, Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3), Decl(spreadUnion2.ts, 23, 3)) + +var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; +>o6 : Symbol(o6, Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3), Decl(spreadUnion2.ts, 23, 3)) +>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 3, 13)) +>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 3, 13)) + +var o6 = { ...nullAndUndefinedUnion }; +>o6 : Symbol(o6, Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3), Decl(spreadUnion2.ts, 23, 3)) +>nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 3, 13)) + diff --git a/tests/baselines/reference/spreadUnion2.types b/tests/baselines/reference/spreadUnion2.types new file mode 100644 index 0000000000000..cf90381ca77f2 --- /dev/null +++ b/tests/baselines/reference/spreadUnion2.types @@ -0,0 +1,84 @@ +=== tests/cases/compiler/spreadUnion2.ts === + +declare const undefinedUnion: { a: number } | undefined; +>undefinedUnion : { a: number; } | undefined +>a : number + +declare const nullUnion: { b: number } | null; +>nullUnion : { b: number; } | null +>b : number +>null : null + +declare const nullAndUndefinedUnion: null | undefined; +>nullAndUndefinedUnion : null | undefined +>null : null + +var o1: { a: number }; +>o1 : { a: number; } +>a : number + +var o1 = { ...undefinedUnion }; +>o1 : { a: number; } +>{ ...undefinedUnion } : { a: number; } +>undefinedUnion : { a: number; } | undefined + +var o2: { b: number }; +>o2 : { b: number; } +>b : number + +var o2 = { ...nullUnion }; +>o2 : { b: number; } +>{ ...nullUnion } : { b: number; } +>nullUnion : { b: number; } | null + +var o3: { a: number, b: number }; +>o3 : { a: number; b: number; } +>a : number +>b : number + +var o3 = { ...undefinedUnion, ...nullUnion }; +>o3 : { a: number; b: number; } +>{ ...undefinedUnion, ...nullUnion } : { b: number; a: number; } +>undefinedUnion : { a: number; } | undefined +>nullUnion : { b: number; } | null + +var o3 = { ...nullUnion, ...undefinedUnion }; +>o3 : { a: number; b: number; } +>{ ...nullUnion, ...undefinedUnion } : { a: number; b: number; } +>nullUnion : { b: number; } | null +>undefinedUnion : { a: number; } | undefined + +var o4: { a: number }; +>o4 : { a: number; } +>a : number + +var o4 = { ...undefinedUnion, ...undefinedUnion }; +>o4 : { a: number; } +>{ ...undefinedUnion, ...undefinedUnion } : { a: number; } +>undefinedUnion : { a: number; } | undefined +>undefinedUnion : { a: number; } | undefined + +var o5: { b: number }; +>o5 : { b: number; } +>b : number + +var o5 = { ...nullUnion, ...nullUnion }; +>o5 : { b: number; } +>{ ...nullUnion, ...nullUnion } : { b: number; } +>nullUnion : { b: number; } | null +>nullUnion : { b: number; } | null + +var o6: { }; +>o6 : {} + +var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; +>o6 : {} +>{ ...nullAndUndefinedUnion, ...nullAndUndefinedUnion } : {} +>nullAndUndefinedUnion : null | undefined +>nullAndUndefinedUnion : null | undefined + +var o6 = { ...nullAndUndefinedUnion }; +>o6 : {} +>{ ...nullAndUndefinedUnion } : {} +>nullAndUndefinedUnion : null | undefined + diff --git a/tests/cases/compiler/declarationEmitIndexTypeNotFound.ts b/tests/cases/compiler/declarationEmitIndexTypeNotFound.ts new file mode 100644 index 0000000000000..de3316cd56f9e --- /dev/null +++ b/tests/cases/compiler/declarationEmitIndexTypeNotFound.ts @@ -0,0 +1,5 @@ +// @declaration: true + +export interface Test { + [index: TypeNotFound]: any; +} diff --git a/tests/cases/compiler/restIntersection.ts b/tests/cases/compiler/restIntersection.ts new file mode 100644 index 0000000000000..5fca2dafc3654 --- /dev/null +++ b/tests/cases/compiler/restIntersection.ts @@ -0,0 +1,4 @@ +var intersection: { x: number, y: number } & { w: string, z: string }; + +var rest1: { y: number, w: string, z: string }; +var {x, ...rest1 } = intersection; diff --git a/tests/cases/compiler/restInvalidArgumentType.ts b/tests/cases/compiler/restInvalidArgumentType.ts new file mode 100644 index 0000000000000..488f546e2310a --- /dev/null +++ b/tests/cases/compiler/restInvalidArgumentType.ts @@ -0,0 +1,59 @@ +enum E { v1, v2 }; + +function f(p1: T, p2: T[]) { + var t: T; + + var i: T["b"]; + var k: keyof T; + + var mapped_generic: {[P in keyof T]: T[P]}; + var mapped: {[P in "b"]: T[P]}; + + var union_generic: T | { a: number }; + var union_primitive: { a: number } | number; + + var intersection_generic: T & { a: number }; + var intersection_premitive: { a: number } | string; + + var num: number; + var str: number; + + var u: undefined; + var n: null; + + var a: any; + + var literal_string: "string"; + var literal_number: 42; + + var e: E; + + var {...r1} = p1; // Error, generic type paramterre + var {...r2} = p2; // OK + var {...r3} = t; // Error, generic type paramter + + var {...r4} = i; // Error, index access + var {...r5} = k; // Error, index + + var {...r6} = mapped_generic; // Error, generic mapped object type + var {...r7} = mapped; // OK, non-generic mapped type + + var {...r8} = union_generic; // Error, union with generic type parameter + var {...r9} = union_primitive; // Error, union with generic type parameter + + var {...r10} = intersection_generic; // Error, intersection with generic type parameter + var {...r11} = intersection_premitive; // Error, intersection with generic type parameter + + var {...r12} = num; // Error + var {...r13} = str; // Error + + var {...r14} = u; // OK + var {...r15} = n; // OK + + var {...r16} = a; // OK + + var {...r17} = literal_string; // Error + var {...r18} = literal_number; // Error + + var {...r19} = e; // Error, enum +} \ No newline at end of file diff --git a/tests/cases/compiler/restUnion.ts b/tests/cases/compiler/restUnion.ts new file mode 100644 index 0000000000000..c838b37340f8d --- /dev/null +++ b/tests/cases/compiler/restUnion.ts @@ -0,0 +1,14 @@ +var union: { a: number, c: boolean } | { a: string, b: string }; + +var rest1: { c: boolean } | { b: string }; +var {a, ...rest1 } = union; + + +var undefinedUnion: { n: number } | undefined; +var rest2: {}; +var {n, ...rest2 } = undefinedUnion; + + +var nullUnion: { n: number } | null; +var rest3: {}; +var {n, ...rest3 } = nullUnion; diff --git a/tests/cases/compiler/restUnion2.ts b/tests/cases/compiler/restUnion2.ts new file mode 100644 index 0000000000000..83d94e03a7365 --- /dev/null +++ b/tests/cases/compiler/restUnion2.ts @@ -0,0 +1,19 @@ +// @strictNullChecks: true + +declare const undefinedUnion: { n: number } | undefined; +var rest2: { n: number }; +var {...rest2 } = undefinedUnion; + + +declare const nullUnion: { n: number } | null; +var rest3: { n: number }; +var {...rest3 } = nullUnion; + + +declare const nullAndUndefinedUnion: null | undefined; +var rest4: { }; +var {...rest4 } = nullAndUndefinedUnion; + +declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined | null; +var rest5: { n: number, s: string }; +var {...rest5 } = unionWithIntersection; \ No newline at end of file diff --git a/tests/cases/compiler/spreadIntersection.ts b/tests/cases/compiler/spreadIntersection.ts new file mode 100644 index 0000000000000..3b397dc40cc0d --- /dev/null +++ b/tests/cases/compiler/spreadIntersection.ts @@ -0,0 +1,7 @@ +var intersection: { a: number } & { b: string }; + +var o1: { a: number, b: string }; +var o1 = { ...intersection }; + +var o2: { a: number, b: string, c: boolean }; +var o2 = { ...intersection, c: false }; \ No newline at end of file diff --git a/tests/cases/compiler/spreadInvalidArgumentType.ts b/tests/cases/compiler/spreadInvalidArgumentType.ts new file mode 100644 index 0000000000000..2ac6aa921f48c --- /dev/null +++ b/tests/cases/compiler/spreadInvalidArgumentType.ts @@ -0,0 +1,59 @@ +enum E { v1, v2 }; + +function f(p1: T, p2: T[]) { + var t: T; + + var i: T["b"]; + var k: keyof T; + + var mapped_generic: {[P in keyof T]: T[P]}; + var mapped: {[P in "b"]: T[P]}; + + var union_generic: T | { a: number }; + var union_primitive: { a: number } | number; + + var intersection_generic: T & { a: number }; + var intersection_premitive: { a: number } | string; + + var num: number; + var str: number; + + var u: undefined; + var n: null; + + var a: any; + + var literal_string: "string"; + var literal_number: 42; + + var e: E; + + var o1 = { ...p1 }; // Error, generic type paramterre + var o2 = { ...p2 }; // OK + var o3 = { ...t }; // Error, generic type paramter + + var o4 = { ...i }; // Error, index access + var o5 = { ...k }; // Error, index + + var o6 = { ...mapped_generic }; // Error, generic mapped object type + var o7 = { ...mapped }; // OK, non-generic mapped type + + var o8 = { ...union_generic }; // Error, union with generic type parameter + var o9 = { ...union_primitive }; // Error, union with generic type parameter + + var o10 = { ...intersection_generic }; // Error, intersection with generic type parameter + var o11 = { ...intersection_premitive }; // Error, intersection with generic type parameter + + var o12 = { ...num }; // Error + var o13 = { ...str }; // Error + + var o14 = { ...u }; // OK + var o15 = { ...n }; // OK + + var o16 = { ...a }; // OK + + var o17 = { ...literal_string }; // Error + var o18 = { ...literal_number }; // Error + + var o19 = { ...e }; // Error, enum +} \ No newline at end of file diff --git a/tests/cases/compiler/spreadUnion.ts b/tests/cases/compiler/spreadUnion.ts new file mode 100644 index 0000000000000..ef8440122ed2b --- /dev/null +++ b/tests/cases/compiler/spreadUnion.ts @@ -0,0 +1,10 @@ +var union: { a: number } | { b: string }; + +var o3: { a: number } | { b: string }; +var o3 = { ...union }; + +var o4: { a: boolean } | { b: string , a: boolean}; +var o4 = { ...union, a: false }; + +var o5: { a: number } | { b: string } | { a: number, b: string }; +var o5 = { ...union, ...union }; \ No newline at end of file diff --git a/tests/cases/compiler/spreadUnion2.ts b/tests/cases/compiler/spreadUnion2.ts new file mode 100644 index 0000000000000..25dba81c0dfca --- /dev/null +++ b/tests/cases/compiler/spreadUnion2.ts @@ -0,0 +1,25 @@ +// @strictNullChecks: true + +declare const undefinedUnion: { a: number } | undefined; +declare const nullUnion: { b: number } | null; +declare const nullAndUndefinedUnion: null | undefined; + +var o1: { a: number }; +var o1 = { ...undefinedUnion }; + +var o2: { b: number }; +var o2 = { ...nullUnion }; + +var o3: { a: number, b: number }; +var o3 = { ...undefinedUnion, ...nullUnion }; +var o3 = { ...nullUnion, ...undefinedUnion }; + +var o4: { a: number }; +var o4 = { ...undefinedUnion, ...undefinedUnion }; + +var o5: { b: number }; +var o5 = { ...nullUnion, ...nullUnion }; + +var o6: { }; +var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; +var o6 = { ...nullAndUndefinedUnion }; \ No newline at end of file diff --git a/tests/cases/conformance/types/mapped/isomorphicMappedTypeInference.ts b/tests/cases/conformance/types/mapped/isomorphicMappedTypeInference.ts index 19a0c4889a50f..4aab2d95ba39b 100644 --- a/tests/cases/conformance/types/mapped/isomorphicMappedTypeInference.ts +++ b/tests/cases/conformance/types/mapped/isomorphicMappedTypeInference.ts @@ -1,3 +1,4 @@ +// @strictNullChecks: true // @noimplicitany: true // @declaration: true @@ -104,4 +105,19 @@ function f6(s: string) { }); let v = unboxify(b); let x: string | number | boolean = v[s]; +} + +declare function validate(obj: { [P in keyof T]?: T[P] }): T; +declare function clone(obj: { readonly [P in keyof T]: T[P] }): T; +declare function validateAndClone(obj: { readonly [P in keyof T]?: T[P] }): T; + +type Foo = { + a?: number; + readonly b: string; +} + +function f10(foo: Foo) { + let x = validate(foo); // { a: number, readonly b: string } + let y = clone(foo); // { a?: number, b: string } + let z = validateAndClone(foo); // { a: number, b: string } } \ No newline at end of file diff --git a/tests/cases/conformance/types/rest/objectRest.ts b/tests/cases/conformance/types/rest/objectRest.ts index 3f7be177c7bb1..2fba5d0b6dcd8 100644 --- a/tests/cases/conformance/types/rest/objectRest.ts +++ b/tests/cases/conformance/types/rest/objectRest.ts @@ -36,3 +36,5 @@ let computed = 'b'; let computed2 = 'a'; var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o; ({ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o); + +var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes']; diff --git a/tests/cases/conformance/types/rest/objectRestNegative.ts b/tests/cases/conformance/types/rest/objectRestNegative.ts index c224c8cd30e34..4f4667fe65a16 100644 --- a/tests/cases/conformance/types/rest/objectRestNegative.ts +++ b/tests/cases/conformance/types/rest/objectRestNegative.ts @@ -1,3 +1,4 @@ +// @noImplicitAny: true let o = { a: 1, b: 'no' }; var { ...mustBeLast, a } = o; @@ -15,3 +16,5 @@ function generic(t: T) { let rest: { b: string } ({a, ...rest.b + rest.b} = o); + +var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes; diff --git a/tests/cases/conformance/types/spread/objectSpreadNegative.ts b/tests/cases/conformance/types/spread/objectSpreadNegative.ts index 3cd819d061350..6d1e0dde42900 100644 --- a/tests/cases/conformance/types/spread/objectSpreadNegative.ts +++ b/tests/cases/conformance/types/spread/objectSpreadNegative.ts @@ -29,9 +29,7 @@ spread = b; // error, missing 's' let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' } let duplicatedSpread = { ...o, ...o } -// null, undefined and primitives are not allowed -let spreadNull = { ...null }; -let spreadUndefind = { ...undefined }; +// primitives are not allowed let spreadNum = { ...12 }; let spreadSum = { ...1 + 1 }; spreadSum.toFixed(); // error, no methods from number