diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 76a1616ce3d..5b8e0712e80 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -204,7 +204,8 @@ namespace ts { // since we are only interested in declarations of the module itself return tryFindAmbientModule(moduleName, /*withAugmentations*/ false); }, - getApparentType + getApparentType, + getBaseConstraintOfType, }; const tupleTypes: GenericType[] = []; @@ -2389,7 +2390,7 @@ namespace ts { const formattedUnionTypes = formatUnionTypes((type).types); const unionTypeNodes = formattedUnionTypes && mapToTypeNodeArray(formattedUnionTypes); if (unionTypeNodes && unionTypeNodes.length > 0) { - return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, unionTypeNodes); + return createUnionTypeNode(unionTypeNodes); } else { if (!context.encounteredError && !(context.flags & NodeBuilderFlags.allowEmptyUnionOrIntersection)) { @@ -2400,7 +2401,7 @@ namespace ts { } if (type.flags & TypeFlags.Intersection) { - return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, mapToTypeNodeArray((type as UnionType).types)); + return createIntersectionTypeNode(mapToTypeNodeArray((type as IntersectionType).types)); } if (objectFlags & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { @@ -2660,7 +2661,7 @@ namespace ts { indexerTypeNode, /*initializer*/ undefined); const typeNode = typeToTypeNodeHelper(indexInfo.type); - return createIndexSignatureDeclaration( + return createIndexSignature( /*decorators*/ undefined, indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined, [indexingParameter], @@ -5777,11 +5778,11 @@ namespace ts { const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfType(type) || emptyObjectType : type; return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(t) : t.flags & TypeFlags.StringLike ? globalStringType : - t.flags & TypeFlags.NumberLike ? globalNumberType : - t.flags & TypeFlags.BooleanLike ? globalBooleanType : - t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2015) : - t.flags & TypeFlags.NonPrimitive ? emptyObjectType : - t; + t.flags & TypeFlags.NumberLike ? globalNumberType : + t.flags & TypeFlags.BooleanLike ? globalBooleanType : + t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2015) : + t.flags & TypeFlags.NonPrimitive ? emptyObjectType : + t; } function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: string): Symbol { @@ -8693,29 +8694,6 @@ namespace ts { return Ternary.False; } - // Check if a property with the given name is known anywhere in the given type. In an object type, a property - // is considered known if the object type is empty and the check is for assignability, if the object type has - // index signatures, or if the property is actually declared in the object type. In a union or intersection - // type, a property is considered known if it is known in any constituent type. - function isKnownProperty(type: Type, name: string, isComparingJsxAttributes: boolean): boolean { - if (type.flags & TypeFlags.Object) { - const resolved = resolveStructuredTypeMembers(type); - if (resolved.stringIndexInfo || resolved.numberIndexInfo && isNumericLiteralName(name) || - getPropertyOfType(type, name) || isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) { - // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known. - return true; - } - } - else if (type.flags & TypeFlags.UnionOrIntersection) { - for (const t of (type).types) { - if (isKnownProperty(t, name, isComparingJsxAttributes)) { - return true; - } - } - } - return false; - } - function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean { if (maybeTypeOfKind(target, TypeFlags.Object) && !(getObjectFlags(target) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) { const isComparingJsxAttributes = !!(source.flags & TypeFlags.JsxAttributes); @@ -10027,7 +10005,7 @@ namespace ts { const templateType = getTemplateTypeFromMappedType(target); const readonlyMask = target.declaration.readonlyToken ? false : true; const optionalMask = target.declaration.questionToken ? 0 : SymbolFlags.Optional; - const members = createSymbolTable(properties); + const members = createMap(); for (const prop of properties) { const inferredPropType = inferTargetType(getTypeOfSymbol(prop)); if (!inferredPropType) { @@ -10444,11 +10422,13 @@ namespace ts { // Return the flow cache key for a "dotted name" (i.e. a sequence of identifiers // separated by dots). The key consists of the id of the symbol referenced by the // leftmost identifier followed by zero or more property names separated by dots. - // The result is undefined if the reference isn't a dotted name. + // The result is undefined if the reference isn't a dotted name. We prefix nodes + // occurring in an apparent type position with '@' because the control flow type + // of such nodes may be based on the apparent type instead of the declared type. function getFlowCacheKey(node: Node): string { if (node.kind === SyntaxKind.Identifier) { const symbol = getResolvedSymbol(node); - return symbol !== unknownSymbol ? "" + getSymbolId(symbol) : undefined; + return symbol !== unknownSymbol ? (isApparentTypePosition(node) ? "@" : "") + getSymbolId(symbol) : undefined; } if (node.kind === SyntaxKind.ThisKeyword) { return "0"; @@ -11713,6 +11693,29 @@ namespace ts { return annotationIncludesUndefined ? getTypeWithFacts(declaredType, TypeFacts.NEUndefined) : declaredType; } + function isApparentTypePosition(node: Node) { + const parent = node.parent; + return parent.kind === SyntaxKind.PropertyAccessExpression || + parent.kind === SyntaxKind.CallExpression && (parent).expression === node || + parent.kind === SyntaxKind.ElementAccessExpression && (parent).expression === node; + } + + function typeHasNullableConstraint(type: Type) { + return type.flags & TypeFlags.TypeVariable && maybeTypeOfKind(getBaseConstraintOfType(type) || emptyObjectType, TypeFlags.Nullable); + } + + function getDeclaredOrApparentType(symbol: Symbol, node: Node) { + // When a node is the left hand expression of a property access, element access, or call expression, + // and the type of the node includes type variables with constraints that are nullable, we fetch the + // apparent type of the node *before* performing control flow analysis such that narrowings apply to + // the constraint type. + const type = getTypeOfSymbol(symbol); + if (isApparentTypePosition(node) && forEachType(type, typeHasNullableConstraint)) { + return mapType(getWidenedType(type), getApparentType); + } + return type; + } + function checkIdentifier(node: Identifier): Type { const symbol = getResolvedSymbol(node); if (symbol === unknownSymbol) { @@ -11788,7 +11791,7 @@ namespace ts { checkCollisionWithCapturedNewTargetVariable(node, node); checkNestedBlockScopedBinding(node, symbol); - const type = getTypeOfSymbol(localOrExportSymbol); + const type = getDeclaredOrApparentType(localOrExportSymbol, node); const declaration = localOrExportSymbol.valueDeclaration; const assignmentKind = getAssignmentTargetKind(node); @@ -13254,6 +13257,8 @@ namespace ts { let spread: Type = emptyObjectType; let attributesArray: Symbol[] = []; let hasSpreadAnyType = false; + let explicitlySpecifyChildrenAttribute = false; + const jsxChildrenPropertyName = getJsxElementChildrenPropertyname(); for (const attributeDecl of attributes.properties) { const member = attributeDecl.symbol; @@ -13272,6 +13277,9 @@ namespace ts { attributeSymbol.target = member; attributesTable.set(attributeSymbol.name, attributeSymbol); attributesArray.push(attributeSymbol); + if (attributeDecl.name.text === jsxChildrenPropertyName) { + explicitlySpecifyChildrenAttribute = true; + } } else { Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute); @@ -13296,19 +13304,15 @@ namespace ts { if (spread !== emptyObjectType) { if (attributesArray.length > 0) { spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable)); - attributesArray = []; - attributesTable = createMap(); } attributesArray = getPropertiesOfType(spread); } attributesTable = createMap(); - if (attributesArray) { - forEach(attributesArray, (attr) => { - if (!filter || filter(attr)) { - attributesTable.set(attr.name, attr); - } - }); + for (const attr of attributesArray) { + if (!filter || filter(attr)) { + attributesTable.set(attr.name, attr); + } } } @@ -13330,11 +13334,11 @@ namespace ts { } } - // Error if there is a attribute named "children" and children element. - // This is because children element will overwrite the value from attributes - const jsxChildrenPropertyName = getJsxElementChildrenPropertyname(); if (!hasSpreadAnyType && jsxChildrenPropertyName && jsxChildrenPropertyName !== "") { - if (attributesTable.has(jsxChildrenPropertyName)) { + // Error if there is a attribute named "children" explicitly specified and children element. + // This is because children element will overwrite the value from attributes. + // Note: we will not warn "children" attribute overwritten if "children" attribute is specified in object spread. + if (explicitlySpecifyChildrenAttribute) { error(attributes, Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, jsxChildrenPropertyName); } @@ -13356,8 +13360,7 @@ namespace ts { */ function createJsxAttributesType(symbol: Symbol, attributesTable: Map) { const result = createAnonymousType(symbol, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); - const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshLiteral; - result.flags |= TypeFlags.JsxAttributes | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag; + result.flags |= TypeFlags.JsxAttributes | TypeFlags.ContainsObjectLiteral; result.objectFlags |= ObjectFlags.ObjectLiteral; return result; } @@ -13876,6 +13879,34 @@ namespace ts { checkJsxAttributesAssignableToTagNameAttributes(node); } + /** + * Check if a property with the given name is known anywhere in the given type. In an object type, a property + * is considered known if the object type is empty and the check is for assignability, if the object type has + * index signatures, or if the property is actually declared in the object type. In a union or intersection + * type, a property is considered known if it is known in any constituent type. + * @param targetType a type to search a given name in + * @param name a property name to search + * @param isComparingJsxAttributes a boolean flag indicating whether we are searching in JsxAttributesType + */ + function isKnownProperty(targetType: Type, name: string, isComparingJsxAttributes: boolean): boolean { + if (targetType.flags & TypeFlags.Object) { + const resolved = resolveStructuredTypeMembers(targetType); + if (resolved.stringIndexInfo || resolved.numberIndexInfo && isNumericLiteralName(name) || + getPropertyOfType(targetType, name) || isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) { + // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known. + return true; + } + } + else if (targetType.flags & TypeFlags.UnionOrIntersection) { + for (const t of (targetType).types) { + if (isKnownProperty(t, name, isComparingJsxAttributes)) { + return true; + } + } + } + return false; + } + /** * Check whether the given attributes of JSX opening-like element is assignable to the tagName attributes. * Get the attributes type of the opening-like element through resolving the tagName, "target attributes" @@ -13908,7 +13939,19 @@ namespace ts { error(openingLikeElement, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, getJsxElementPropertiesName()); } else { - checkTypeAssignableTo(sourceAttributesType, targetAttributesType, openingLikeElement.attributes.properties.length > 0 ? openingLikeElement.attributes : openingLikeElement); + // Check if sourceAttributesType assignable to targetAttributesType though this check will allow excess properties + const isSourceAttributeTypeAssignableToTarget = checkTypeAssignableTo(sourceAttributesType, targetAttributesType, openingLikeElement.attributes.properties.length > 0 ? openingLikeElement.attributes : openingLikeElement); + // After we check for assignability, we will do another pass to check that all explicitly specified attributes have correct name corresponding in targetAttributeType. + // This will allow excess properties in spread type as it is very common pattern to spread outter attributes into React component in its render method. + if (isSourceAttributeTypeAssignableToTarget && !isTypeAny(sourceAttributesType) && !isTypeAny(targetAttributesType)) { + for (const attribute of openingLikeElement.attributes.properties) { + if (isJsxAttribute(attribute) && !isKnownProperty(targetAttributesType, attribute.name.text, /*isComparingJsxAttributes*/ true)) { + error(attribute, Diagnostics.Property_0_does_not_exist_on_type_1, attribute.name.text, typeToString(targetAttributesType)); + // We break here so that errors won't be cascading + break; + } + } + } } } @@ -14161,7 +14204,7 @@ namespace ts { checkPropertyAccessibility(node, left, apparentType, prop); - const propType = getTypeOfSymbol(prop); + const propType = getDeclaredOrApparentType(prop, node); const assignmentKind = getAssignmentTargetKind(node); if (assignmentKind) { @@ -20659,11 +20702,6 @@ namespace ts { continue; } - if ((baseDeclarationFlags & ModifierFlags.Static) !== (derivedDeclarationFlags & ModifierFlags.Static)) { - // value of 'static' is not the same for properties - not override, skip it - continue; - } - if (isMethodLike(base) && isMethodLike(derived) || base.flags & SymbolFlags.PropertyOrAccessor && derived.flags & SymbolFlags.PropertyOrAccessor) { // method is overridden with method or property/accessor is overridden with property/accessor - correct case continue; @@ -22756,16 +22794,6 @@ namespace ts { getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags); } - function writeBaseConstructorTypeOfClass(node: ClassLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) { - const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(node)); - resolveBaseTypesOfClass(classType); - const baseType = classType.resolvedBaseTypes.length ? classType.resolvedBaseTypes[0] : unknownType; - if (!baseType.symbol) { - writer.reportIllegalExtends(); - } - getSymbolDisplayBuilder().buildTypeDisplay(baseType, writer, enclosingDeclaration, flags); - } - function hasGlobalName(name: string): boolean { return globals.has(name); } @@ -22859,7 +22887,6 @@ namespace ts { writeTypeOfDeclaration, writeReturnTypeOfSignatureDeclaration, writeTypeOfExpression, - writeBaseConstructorTypeOfClass, isSymbolAccessible, isEntityNameVisible, getConstantValue: node => { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index a5990a5a31b..9494098c072 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1088,58 +1088,38 @@ namespace ts { * @param host Instance of ParseConfigHost used to enumerate files in folder. * @param basePath A root directory to resolve relative path entries in the config * file to. e.g. outDir + * @param resolutionStack Only present for backwards-compatibility. Should be empty. */ - export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string, resolutionStack: Path[] = [], extraFileExtensions: JsFileExtensionInfo[] = []): ParsedCommandLine { + export function parseJsonConfigFileContent( + json: any, + host: ParseConfigHost, + basePath: string, + existingOptions: CompilerOptions = {}, + configFileName?: string, + resolutionStack: Path[] = [], + extraFileExtensions: JsFileExtensionInfo[] = [], + ): ParsedCommandLine { const errors: Diagnostic[] = []; - basePath = normalizeSlashes(basePath); - const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames); - const resolvedPath = toPath(configFileName || "", basePath, getCanonicalFileName); - if (resolutionStack.indexOf(resolvedPath) >= 0) { - return { - options: {}, - fileNames: [], - typeAcquisition: {}, - raw: json, - errors: [createCompilerDiagnostic(Diagnostics.Circularity_detected_while_resolving_configuration_Colon_0, [...resolutionStack, resolvedPath].join(" -> "))], - wildcardDirectories: {} - }; - } - let options: CompilerOptions = convertCompilerOptionsFromJsonWorker(json["compilerOptions"], basePath, errors, configFileName); + let options = (() => { + const { include, exclude, files, options, compileOnSave } = parseConfig(json, host, basePath, configFileName, resolutionStack, errors); + if (include) { json.include = include; } + if (exclude) { json.exclude = exclude; } + if (files) { json.files = files; } + if (compileOnSave !== undefined) { json.compileOnSave = compileOnSave; } + return options; + })(); + + options = extend(existingOptions, options); + options.configFilePath = configFileName; + // typingOptions has been deprecated and is only supported for backward compatibility purposes. // It should be removed in future releases - use typeAcquisition instead. const jsonOptions = json["typeAcquisition"] || json["typingOptions"]; const typeAcquisition: TypeAcquisition = convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName); - let baseCompileOnSave: boolean; - if (json["extends"]) { - let [include, exclude, files, baseOptions]: [string[], string[], string[], CompilerOptions] = [undefined, undefined, undefined, {}]; - if (typeof json["extends"] === "string") { - [include, exclude, files, baseCompileOnSave, baseOptions] = (tryExtendsName(json["extends"]) || [include, exclude, files, baseCompileOnSave, baseOptions]); - } - else { - errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "extends", "string")); - } - if (include && !json["include"]) { - json["include"] = include; - } - if (exclude && !json["exclude"]) { - json["exclude"] = exclude; - } - if (files && !json["files"]) { - json["files"] = files; - } - options = assign({}, baseOptions, options); - } - - options = extend(existingOptions, options); - options.configFilePath = configFileName; - - const { fileNames, wildcardDirectories } = getFileNames(errors); - let compileOnSave = convertCompileOnSaveOptionFromJson(json, basePath, errors); - if (baseCompileOnSave && json[compileOnSaveCommandLineOption.name] === undefined) { - compileOnSave = baseCompileOnSave; - } + const { fileNames, wildcardDirectories } = getFileNames(); + const compileOnSave = convertCompileOnSaveOptionFromJson(json, basePath, errors); return { options, @@ -1151,40 +1131,7 @@ namespace ts { compileOnSave }; - function tryExtendsName(extendedConfig: string): [string[], string[], string[], boolean, CompilerOptions] { - // If the path isn't a rooted or relative path, don't try to resolve it (we reserve the right to special case module-id like paths in the future) - if (!(isRootedDiskPath(extendedConfig) || startsWith(normalizeSlashes(extendedConfig), "./") || startsWith(normalizeSlashes(extendedConfig), "../"))) { - errors.push(createCompilerDiagnostic(Diagnostics.A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not, extendedConfig)); - return; - } - let extendedConfigPath = toPath(extendedConfig, basePath, getCanonicalFileName); - if (!host.fileExists(extendedConfigPath) && !endsWith(extendedConfigPath, ".json")) { - extendedConfigPath = `${extendedConfigPath}.json` as Path; - if (!host.fileExists(extendedConfigPath)) { - errors.push(createCompilerDiagnostic(Diagnostics.File_0_does_not_exist, extendedConfig)); - return; - } - } - const extendedResult = readConfigFile(extendedConfigPath, path => host.readFile(path)); - if (extendedResult.error) { - errors.push(extendedResult.error); - return; - } - const extendedDirname = getDirectoryPath(extendedConfigPath); - const relativeDifference = convertToRelativePath(extendedDirname, basePath, getCanonicalFileName); - const updatePath: (path: string) => string = path => isRootedDiskPath(path) ? path : combinePaths(relativeDifference, path); - // Merge configs (copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios) - const result = parseJsonConfigFileContent(extendedResult.config, host, extendedDirname, /*existingOptions*/ undefined, getBaseFileName(extendedConfigPath), resolutionStack.concat([resolvedPath])); - errors.push(...result.errors); - const [include, exclude, files] = map(["include", "exclude", "files"], key => { - if (!json[key] && extendedResult.config[key]) { - return map(extendedResult.config[key], updatePath); - } - }); - return [include, exclude, files, result.compileOnSave, result.options]; - } - - function getFileNames(errors: Diagnostic[]): ExpandResult { + function getFileNames(): ExpandResult { let fileNames: string[]; if (hasProperty(json, "files")) { if (isArray(json["files"])) { @@ -1217,9 +1164,6 @@ namespace ts { errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "exclude", "Array")); } } - else if (hasProperty(json, "excludes")) { - errors.push(createCompilerDiagnostic(Diagnostics.Unknown_option_excludes_Did_you_mean_exclude)); - } else { // If no includes were specified, exclude common package folders and the outDir excludeSpecs = includeSpecs ? [] : ["node_modules", "bower_components", "jspm_packages"]; @@ -1249,7 +1193,106 @@ namespace ts { } } - export function convertCompileOnSaveOptionFromJson(jsonOption: any, basePath: string, errors: Diagnostic[]): boolean | undefined { + interface ParsedTsconfig { + include: string[] | undefined; + exclude: string[] | undefined; + files: string[] | undefined; + options: CompilerOptions; + compileOnSave: boolean | undefined; + } + + /** + * This *just* extracts options/include/exclude/files out of a config file. + * It does *not* resolve the included files. + */ + function parseConfig( + json: any, + host: ParseConfigHost, + basePath: string, + configFileName: string, + resolutionStack: Path[], + errors: Diagnostic[], + ): ParsedTsconfig { + + basePath = normalizeSlashes(basePath); + const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames); + const resolvedPath = toPath(configFileName || "", basePath, getCanonicalFileName); + + if (resolutionStack.indexOf(resolvedPath) >= 0) { + errors.push(createCompilerDiagnostic(Diagnostics.Circularity_detected_while_resolving_configuration_Colon_0, [...resolutionStack, resolvedPath].join(" -> "))); + return { include: undefined, exclude: undefined, files: undefined, options: {}, compileOnSave: undefined }; + } + + if (hasProperty(json, "excludes")) { + errors.push(createCompilerDiagnostic(Diagnostics.Unknown_option_excludes_Did_you_mean_exclude)); + } + + let options: CompilerOptions = convertCompilerOptionsFromJsonWorker(json.compilerOptions, basePath, errors, configFileName); + let include: string[] | undefined = json.include, exclude: string[] | undefined = json.exclude, files: string[] | undefined = json.files; + let compileOnSave: boolean | undefined = json.compileOnSave; + + if (json.extends) { + // copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios. + resolutionStack = resolutionStack.concat([resolvedPath]); + const base = getExtendedConfig(json.extends, host, basePath, getCanonicalFileName, resolutionStack, errors); + if (base) { + include = include || base.include; + exclude = exclude || base.exclude; + files = files || base.files; + if (compileOnSave === undefined) { + compileOnSave = base.compileOnSave; + } + options = assign({}, base.options, options); + } + } + + return { include, exclude, files, options, compileOnSave }; + } + + function getExtendedConfig( + extended: any, // Usually a string. + host: ts.ParseConfigHost, + basePath: string, + getCanonicalFileName: (fileName: string) => string, + resolutionStack: Path[], + errors: Diagnostic[], + ): ParsedTsconfig | undefined { + if (typeof extended !== "string") { + errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "extends", "string")); + return undefined; + } + + extended = normalizeSlashes(extended); + + // If the path isn't a rooted or relative path, don't try to resolve it (we reserve the right to special case module-id like paths in the future) + if (!(isRootedDiskPath(extended) || startsWith(extended, "./") || startsWith(extended, "../"))) { + errors.push(createCompilerDiagnostic(Diagnostics.A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not, extended)); + return undefined; + } + + let extendedConfigPath = toPath(extended, basePath, getCanonicalFileName); + if (!host.fileExists(extendedConfigPath) && !endsWith(extendedConfigPath, ".json")) { + extendedConfigPath = extendedConfigPath + ".json" as Path; + if (!host.fileExists(extendedConfigPath)) { + errors.push(createCompilerDiagnostic(Diagnostics.File_0_does_not_exist, extended)); + return undefined; + } + } + + const extendedResult = readConfigFile(extendedConfigPath, path => host.readFile(path)); + if (extendedResult.error) { + errors.push(extendedResult.error); + return undefined; + } + + const extendedDirname = getDirectoryPath(extendedConfigPath); + const relativeDifference = convertToRelativePath(extendedDirname, basePath, getCanonicalFileName); + const updatePath: (path: string) => string = path => isRootedDiskPath(path) ? path : combinePaths(relativeDifference, path); + const { include, exclude, files, options, compileOnSave } = parseConfig(extendedResult.config, host, extendedDirname, getBaseFileName(extendedConfigPath), resolutionStack, errors); + return { include: map(include, updatePath), exclude: map(exclude, updatePath), files: map(files, updatePath), compileOnSave, options }; + } + + export function convertCompileOnSaveOptionFromJson(jsonOption: any, basePath: string, errors: Diagnostic[]): boolean { if (!hasProperty(jsonOption, compileOnSaveCommandLineOption.name)) { return false; } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 0a7f9a2a3ec..212a4b6e177 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -594,12 +594,11 @@ namespace ts { emitLines(node.statements); } - // Return a temp variable name to be used in `export default` statements. + // Return a temp variable name to be used in `export default`/`export class ... extends` statements. // The temp name will be of the form _default_counter. // Note that export default is only allowed at most once in a module, so we // do not need to keep track of created temp names. - function getExportDefaultTempVariableName(): string { - const baseName = "_default"; + function getExportTempVariableName(baseName: string): string { if (!currentIdentifiers.has(baseName)) { return baseName; } @@ -613,24 +612,31 @@ namespace ts { } } + function emitTempVariableDeclaration(expr: Expression, baseName: string, diagnostic: SymbolAccessibilityDiagnostic): string { + const tempVarName = getExportTempVariableName(baseName); + if (!noDeclare) { + write("declare "); + } + write("const "); + write(tempVarName); + write(": "); + writer.getSymbolAccessibilityDiagnostic = () => diagnostic; + resolver.writeTypeOfExpression(expr, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer); + write(";"); + writeLine(); + return tempVarName; + } + function emitExportAssignment(node: ExportAssignment) { if (node.expression.kind === SyntaxKind.Identifier) { write(node.isExportEquals ? "export = " : "export default "); writeTextOfNode(currentText, node.expression); } else { - // Expression - const tempVarName = getExportDefaultTempVariableName(); - if (!noDeclare) { - write("declare "); - } - write("var "); - write(tempVarName); - write(": "); - writer.getSymbolAccessibilityDiagnostic = getDefaultExportAccessibilityDiagnostic; - resolver.writeTypeOfExpression(node.expression, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer); - write(";"); - writeLine(); + const tempVarName = emitTempVariableDeclaration(node.expression, "_default", { + diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0, + errorNode: node + }); write(node.isExportEquals ? "export = " : "export default "); write(tempVarName); } @@ -644,13 +650,6 @@ namespace ts { // write each of these declarations asynchronously writeAsynchronousModuleElements(nodes); } - - function getDefaultExportAccessibilityDiagnostic(): SymbolAccessibilityDiagnostic { - return { - diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0, - errorNode: node - }; - } } function isModuleElementVisible(node: Declaration) { @@ -1097,7 +1096,7 @@ namespace ts { } } - function emitHeritageClause(className: Identifier, typeReferences: ExpressionWithTypeArguments[], isImplementsList: boolean) { + function emitHeritageClause(typeReferences: ExpressionWithTypeArguments[], isImplementsList: boolean) { if (typeReferences) { write(isImplementsList ? " implements " : " extends "); emitCommaList(typeReferences, emitTypeOfTypeReference); @@ -1110,12 +1109,6 @@ namespace ts { else if (!isImplementsList && node.expression.kind === SyntaxKind.NullKeyword) { write("null"); } - else { - writer.getSymbolAccessibilityDiagnostic = getHeritageClauseVisibilityError; - errorNameNode = className; - resolver.writeBaseConstructorTypeOfClass(enclosingDeclaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer); - errorNameNode = undefined; - } function getHeritageClauseVisibilityError(): SymbolAccessibilityDiagnostic { let diagnosticMessage: DiagnosticMessage; @@ -1151,23 +1144,43 @@ namespace ts { } } + const prevEnclosingDeclaration = enclosingDeclaration; + enclosingDeclaration = node; + const baseTypeNode = getClassExtendsHeritageClauseElement(node); + let tempVarName: string; + if (baseTypeNode && !isEntityNameExpression(baseTypeNode.expression)) { + tempVarName = baseTypeNode.expression.kind === SyntaxKind.NullKeyword ? + "null" : + emitTempVariableDeclaration(baseTypeNode.expression, `${node.name.text}_base`, { + diagnosticMessage: Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1, + errorNode: baseTypeNode, + typeName: node.name + }); + } + emitJsDocComments(node); emitModuleElementDeclarationFlags(node); if (hasModifier(node, ModifierFlags.Abstract)) { write("abstract "); } - write("class "); writeTextOfNode(currentText, node.name); - const prevEnclosingDeclaration = enclosingDeclaration; - enclosingDeclaration = node; emitTypeParameters(node.typeParameters); - const baseTypeNode = getClassExtendsHeritageClauseElement(node); if (baseTypeNode) { - node.name; - emitHeritageClause(node.name, [baseTypeNode], /*isImplementsList*/ false); + if (!isEntityNameExpression(baseTypeNode.expression)) { + write(" extends "); + write(tempVarName); + if (baseTypeNode.typeArguments) { + write("<"); + emitCommaList(baseTypeNode.typeArguments, emitType); + write(">"); + } + } + else { + emitHeritageClause([baseTypeNode], /*isImplementsList*/ false); + } } - emitHeritageClause(node.name, getClassImplementsHeritageClauseElements(node), /*isImplementsList*/ true); + emitHeritageClause(getClassImplementsHeritageClauseElements(node), /*isImplementsList*/ true); write(" {"); writeLine(); increaseIndent(); @@ -1189,7 +1202,7 @@ namespace ts { emitTypeParameters(node.typeParameters); const interfaceExtendsTypes = filter(getInterfaceBaseTypeNodes(node), base => isEntityNameExpression(base.expression)); if (interfaceExtendsTypes && interfaceExtendsTypes.length) { - emitHeritageClause(node.name, interfaceExtendsTypes, /*isImplementsList*/ false); + emitHeritageClause(interfaceExtendsTypes, /*isImplementsList*/ false); } write(" {"); writeLine(); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 1a8b91c8ff2..2b781b6dbb3 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -214,248 +214,14 @@ namespace ts { : node; } - // Type Elements - - export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { - const signatureDeclaration = createSynthesizedNode(kind) as SignatureDeclaration; - signatureDeclaration.typeParameters = asNodeArray(typeParameters); - signatureDeclaration.parameters = asNodeArray(parameters); - signatureDeclaration.type = type; - return signatureDeclaration; - } - - function updateSignatureDeclaration(node: SignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { - return node.typeParameters !== typeParameters - || node.parameters !== parameters - || node.type !== type - ? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node) - : node; - } - - export function createFunctionTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { - return createSignatureDeclaration(SyntaxKind.FunctionType, typeParameters, parameters, type) as FunctionTypeNode; - } - - export function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { - return updateSignatureDeclaration(node, typeParameters, parameters, type); - } - - export function createConstructorTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { - return createSignatureDeclaration(SyntaxKind.ConstructorType, typeParameters, parameters, type) as ConstructorTypeNode; - } - - export function updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { - return updateSignatureDeclaration(node, typeParameters, parameters, type); - } - - export function createCallSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { - return createSignatureDeclaration(SyntaxKind.CallSignature, typeParameters, parameters, type) as CallSignatureDeclaration; - } - - export function updateCallSignatureDeclaration(node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { - return updateSignatureDeclaration(node, typeParameters, parameters, type); - } - - export function createConstructSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { - return createSignatureDeclaration(SyntaxKind.ConstructSignature, typeParameters, parameters, type) as ConstructSignatureDeclaration; - } - - export function updateConstructSignatureDeclaration(node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { - return updateSignatureDeclaration(node, typeParameters, parameters, type); - } - - export function createMethodSignature(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined) { - const methodSignature = createSignatureDeclaration(SyntaxKind.MethodSignature, typeParameters, parameters, type) as MethodSignature; - methodSignature.name = asName(name); - methodSignature.questionToken = questionToken; - return methodSignature; - } - - export function updateMethodSignature(node: MethodSignature, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined) { - return node.typeParameters !== typeParameters - || node.parameters !== parameters - || node.type !== type - || node.name !== name - || node.questionToken !== questionToken - ? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node) - : node; - } - - // Types - - export function createKeywordTypeNode(kind: KeywordTypeNode["kind"]) { - return createSynthesizedNode(kind); - } - - export function createThisTypeNode() { - return createSynthesizedNode(SyntaxKind.ThisType); - } - - export function createLiteralTypeNode(literal: Expression) { - const literalTypeNode = createSynthesizedNode(SyntaxKind.LiteralType) as LiteralTypeNode; - literalTypeNode.literal = literal; - return literalTypeNode; - } - - export function updateLiteralTypeNode(node: LiteralTypeNode, literal: Expression) { - return node.literal !== literal - ? updateNode(createLiteralTypeNode(literal), node) - : node; - } - - export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: TypeNode[] | undefined) { - const typeReference = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; - typeReference.typeName = asName(typeName); - typeReference.typeArguments = asNodeArray(typeArguments); - return typeReference; - } - - export function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined) { - return node.typeName !== typeName - || node.typeArguments !== typeArguments - ? updateNode(createTypeReferenceNode(typeName, typeArguments), node) - : node; - } - - export function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode) { - const typePredicateNode = createSynthesizedNode(SyntaxKind.TypePredicate) as TypePredicateNode; - typePredicateNode.parameterName = asName(parameterName); - typePredicateNode.type = type; - return typePredicateNode; - } - - export function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode) { - return node.parameterName !== parameterName - || node.type !== type - ? updateNode(createTypePredicateNode(parameterName, type), node) - : node; - } - - export function createTypeQueryNode(exprName: EntityName) { - const typeQueryNode = createSynthesizedNode(SyntaxKind.TypeQuery) as TypeQueryNode; - typeQueryNode.exprName = exprName; - return typeQueryNode; - } - - export function updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName) { - return node.exprName !== exprName ? updateNode(createTypeQueryNode(exprName), node) : node; - } - - export function createArrayTypeNode(elementType: TypeNode) { - const arrayTypeNode = createSynthesizedNode(SyntaxKind.ArrayType) as ArrayTypeNode; - arrayTypeNode.elementType = elementType; - return arrayTypeNode; - } - - export function updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode { - return node.elementType !== elementType - ? updateNode(createArrayTypeNode(elementType), node) - : node; - } - - export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType, types: TypeNode[]): UnionTypeNode; - export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.IntersectionType, types: TypeNode[]): IntersectionTypeNode; - export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]): UnionOrIntersectionTypeNode; - export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]) { - const unionTypeNode = createSynthesizedNode(kind) as UnionTypeNode | IntersectionTypeNode; - unionTypeNode.types = createNodeArray(types); - return unionTypeNode; - } - - export function updateUnionOrIntersectionTypeNode(node: UnionOrIntersectionTypeNode, types: NodeArray) { - return node.types !== types - ? updateNode(createUnionOrIntersectionTypeNode(node.kind, types), node) - : node; - } - - export function createParenthesizedType(type: TypeNode) { - const node = createSynthesizedNode(SyntaxKind.ParenthesizedType); - node.type = type; - return node; - } - - export function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode) { - return node.type !== type - ? updateNode(createParenthesizedType(type), node) - : node; - } - - export function createTypeLiteralNode(members: TypeElement[]) { - const typeLiteralNode = createSynthesizedNode(SyntaxKind.TypeLiteral) as TypeLiteralNode; - typeLiteralNode.members = createNodeArray(members); - return typeLiteralNode; - } - - export function updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray) { - return node.members !== members - ? updateNode(createTypeLiteralNode(members), node) - : node; - } - - export function createTupleTypeNode(elementTypes: TypeNode[]) { - const tupleTypeNode = createSynthesizedNode(SyntaxKind.TupleType) as TupleTypeNode; - tupleTypeNode.elementTypes = createNodeArray(elementTypes); - return tupleTypeNode; - } - - export function updateTypleTypeNode(node: TupleTypeNode, elementTypes: TypeNode[]) { - return node.elementTypes !== elementTypes - ? updateNode(createTupleTypeNode(elementTypes), node) - : node; - } - - export function createMappedTypeNode(readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode { - const mappedTypeNode = createSynthesizedNode(SyntaxKind.MappedType) as MappedTypeNode; - mappedTypeNode.readonlyToken = readonlyToken; - mappedTypeNode.typeParameter = typeParameter; - mappedTypeNode.questionToken = questionToken; - mappedTypeNode.type = type; - return mappedTypeNode; - } - - export function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode { - return node.readonlyToken !== readonlyToken - || node.typeParameter !== typeParameter - || node.questionToken !== questionToken - || node.type !== type - ? updateNode(createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), node) - : node; - } - - export function createTypeOperatorNode(type: TypeNode) { - const typeOperatorNode = createSynthesizedNode(SyntaxKind.TypeOperator) as TypeOperatorNode; - typeOperatorNode.operator = SyntaxKind.KeyOfKeyword; - typeOperatorNode.type = type; - return typeOperatorNode; - } - - export function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode) { - return node.type !== type ? updateNode(createTypeOperatorNode(type), node) : node; - } - - export function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode) { - const indexedAccessTypeNode = createSynthesizedNode(SyntaxKind.IndexedAccessType) as IndexedAccessTypeNode; - indexedAccessTypeNode.objectType = objectType; - indexedAccessTypeNode.indexType = indexType; - return indexedAccessTypeNode; - } - - export function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) { - return node.objectType !== objectType - || node.indexType !== indexType - ? updateNode(createIndexedAccessTypeNode(objectType, indexType), node) - : node; - } - - // Type Declarations + // Signature elements export function createTypeParameterDeclaration(name: string | Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined) { - const typeParameter = createSynthesizedNode(SyntaxKind.TypeParameter) as TypeParameterDeclaration; - typeParameter.name = asName(name); - typeParameter.constraint = constraint; - typeParameter.default = defaultType; - - return typeParameter; + const node = createSynthesizedNode(SyntaxKind.TypeParameter) as TypeParameterDeclaration; + node.name = asName(name); + node.constraint = constraint; + node.default = defaultType; + return node; } export function updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined) { @@ -466,46 +232,6 @@ namespace ts { : node; } - // Signature elements - - export function createPropertySignature(name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature { - const propertySignature = createSynthesizedNode(SyntaxKind.PropertySignature) as PropertySignature; - propertySignature.name = asName(name); - propertySignature.questionToken = questionToken; - propertySignature.type = type; - propertySignature.initializer = initializer; - return propertySignature; - } - - export function updatePropertySignature(node: PropertySignature, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { - return node.name !== name - || node.questionToken !== questionToken - || node.type !== type - || node.initializer !== initializer - ? updateNode(createPropertySignature(name, questionToken, type, initializer), node) - : node; - } - - export function createIndexSignatureDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration { - const indexSignature = createSynthesizedNode(SyntaxKind.IndexSignature) as IndexSignatureDeclaration; - indexSignature.decorators = asNodeArray(decorators); - indexSignature.modifiers = asNodeArray(modifiers); - indexSignature.parameters = createNodeArray(parameters); - indexSignature.type = type; - return indexSignature; - } - - export function updateIndexSignatureDeclaration(node: IndexSignatureDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], type: TypeNode) { - return node.parameters !== parameters - || node.type !== type - || node.decorators !== decorators - || node.modifiers !== modifiers - ? updateNode(createIndexSignatureDeclaration(decorators, modifiers, parameters, type), node) - : node; - } - - // Signature elements - export function createParameter(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) { const node = createSynthesizedNode(SyntaxKind.Parameter); node.decorators = asNodeArray(decorators); @@ -542,7 +268,26 @@ namespace ts { : node; } - // Type members + + // Type Elements + + export function createPropertySignature(name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature { + const node = createSynthesizedNode(SyntaxKind.PropertySignature) as PropertySignature; + node.name = asName(name); + node.questionToken = questionToken; + node.type = type; + node.initializer = initializer; + return node; + } + + export function updatePropertySignature(node: PropertySignature, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { + return node.name !== name + || node.questionToken !== questionToken + || node.type !== type + || node.initializer !== initializer + ? updateNode(createPropertySignature(name, questionToken, type, initializer), node) + : node; + } export function createProperty(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression) { const node = createSynthesizedNode(SyntaxKind.PropertyDeclaration); @@ -565,7 +310,24 @@ namespace ts { : node; } - export function createMethodDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { + export function createMethodSignature(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined) { + const node = createSignatureDeclaration(SyntaxKind.MethodSignature, typeParameters, parameters, type) as MethodSignature; + node.name = asName(name); + node.questionToken = questionToken; + return node; + } + + export function updateMethodSignature(node: MethodSignature, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined) { + return node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + || node.name !== name + || node.questionToken !== questionToken + ? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node) + : node; + } + + export function createMethod(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { const node = createSynthesizedNode(SyntaxKind.MethodDeclaration); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); @@ -588,7 +350,7 @@ namespace ts { || node.parameters !== parameters || node.type !== type || node.body !== body - ? updateNode(createMethodDeclaration(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node) + ? updateNode(createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node) : node; } @@ -656,6 +418,254 @@ namespace ts { : node; } + export function createCallSignature(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { + return createSignatureDeclaration(SyntaxKind.CallSignature, typeParameters, parameters, type) as CallSignatureDeclaration; + } + + export function updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { + return updateSignatureDeclaration(node, typeParameters, parameters, type); + } + + export function createConstructSignature(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { + return createSignatureDeclaration(SyntaxKind.ConstructSignature, typeParameters, parameters, type) as ConstructSignatureDeclaration; + } + + export function updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { + return updateSignatureDeclaration(node, typeParameters, parameters, type); + } + + export function createIndexSignature(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], type: TypeNode): IndexSignatureDeclaration { + const node = createSynthesizedNode(SyntaxKind.IndexSignature) as IndexSignatureDeclaration; + node.decorators = asNodeArray(decorators); + node.modifiers = asNodeArray(modifiers); + node.parameters = createNodeArray(parameters); + node.type = type; + return node; + } + + export function updateIndexSignature(node: IndexSignatureDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], type: TypeNode) { + return node.parameters !== parameters + || node.type !== type + || node.decorators !== decorators + || node.modifiers !== modifiers + ? updateNode(createIndexSignature(decorators, modifiers, parameters, type), node) + : node; + } + + /* @internal */ + export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { + const node = createSynthesizedNode(kind) as SignatureDeclaration; + node.typeParameters = asNodeArray(typeParameters); + node.parameters = asNodeArray(parameters); + node.type = type; + return node; + } + + function updateSignatureDeclaration(node: T, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined): T { + return node.typeParameters !== typeParameters + || node.parameters !== parameters + || node.type !== type + ? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node) + : node; + } + + // Types + + export function createKeywordTypeNode(kind: KeywordTypeNode["kind"]) { + return createSynthesizedNode(kind); + } + + export function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode) { + const node = createSynthesizedNode(SyntaxKind.TypePredicate) as TypePredicateNode; + node.parameterName = asName(parameterName); + node.type = type; + return node; + } + + export function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode) { + return node.parameterName !== parameterName + || node.type !== type + ? updateNode(createTypePredicateNode(parameterName, type), node) + : node; + } + + export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: TypeNode[] | undefined) { + const node = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode; + node.typeName = asName(typeName); + node.typeArguments = asNodeArray(typeArguments); + return node; + } + + export function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined) { + return node.typeName !== typeName + || node.typeArguments !== typeArguments + ? updateNode(createTypeReferenceNode(typeName, typeArguments), node) + : node; + } + + export function createFunctionTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { + return createSignatureDeclaration(SyntaxKind.FunctionType, typeParameters, parameters, type) as FunctionTypeNode; + } + + export function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { + return updateSignatureDeclaration(node, typeParameters, parameters, type); + } + + export function createConstructorTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) { + return createSignatureDeclaration(SyntaxKind.ConstructorType, typeParameters, parameters, type) as ConstructorTypeNode; + } + + export function updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined) { + return updateSignatureDeclaration(node, typeParameters, parameters, type); + } + + export function createTypeQueryNode(exprName: EntityName) { + const node = createSynthesizedNode(SyntaxKind.TypeQuery) as TypeQueryNode; + node.exprName = exprName; + return node; + } + + export function updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName) { + return node.exprName !== exprName + ? updateNode(createTypeQueryNode(exprName), node) + : node; + } + + export function createTypeLiteralNode(members: TypeElement[]) { + const node = createSynthesizedNode(SyntaxKind.TypeLiteral) as TypeLiteralNode; + node.members = createNodeArray(members); + return node; + } + + export function updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray) { + return node.members !== members + ? updateNode(createTypeLiteralNode(members), node) + : node; + } + + export function createArrayTypeNode(elementType: TypeNode) { + const node = createSynthesizedNode(SyntaxKind.ArrayType) as ArrayTypeNode; + node.elementType = elementType; + return node; + } + + export function updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode { + return node.elementType !== elementType + ? updateNode(createArrayTypeNode(elementType), node) + : node; + } + + export function createTupleTypeNode(elementTypes: TypeNode[]) { + const node = createSynthesizedNode(SyntaxKind.TupleType) as TupleTypeNode; + node.elementTypes = createNodeArray(elementTypes); + return node; + } + + export function updateTypleTypeNode(node: TupleTypeNode, elementTypes: TypeNode[]) { + return node.elementTypes !== elementTypes + ? updateNode(createTupleTypeNode(elementTypes), node) + : node; + } + + export function createUnionTypeNode(types: TypeNode[]): UnionTypeNode { + return createUnionOrIntersectionTypeNode(SyntaxKind.UnionType, types); + } + + export function updateUnionTypeNode(node: UnionTypeNode, types: NodeArray) { + return updateUnionOrIntersectionTypeNode(node, types); + } + + export function createIntersectionTypeNode(types: TypeNode[]): IntersectionTypeNode { + return createUnionOrIntersectionTypeNode(SyntaxKind.IntersectionType, types); + } + + export function updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray) { + return updateUnionOrIntersectionTypeNode(node, types); + } + + export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]) { + const node = createSynthesizedNode(kind) as UnionTypeNode | IntersectionTypeNode; + node.types = createNodeArray(types); + return node; + } + + function updateUnionOrIntersectionTypeNode(node: T, types: NodeArray): T { + return node.types !== types + ? updateNode(createUnionOrIntersectionTypeNode(node.kind, types), node) + : node; + } + + export function createParenthesizedType(type: TypeNode) { + const node = createSynthesizedNode(SyntaxKind.ParenthesizedType); + node.type = type; + return node; + } + + export function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode) { + return node.type !== type + ? updateNode(createParenthesizedType(type), node) + : node; + } + + export function createThisTypeNode() { + return createSynthesizedNode(SyntaxKind.ThisType); + } + + export function createTypeOperatorNode(type: TypeNode) { + const node = createSynthesizedNode(SyntaxKind.TypeOperator) as TypeOperatorNode; + node.operator = SyntaxKind.KeyOfKeyword; + node.type = type; + return node; + } + + export function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode) { + return node.type !== type ? updateNode(createTypeOperatorNode(type), node) : node; + } + + export function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode) { + const node = createSynthesizedNode(SyntaxKind.IndexedAccessType) as IndexedAccessTypeNode; + node.objectType = objectType; + node.indexType = indexType; + return node; + } + + export function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) { + return node.objectType !== objectType + || node.indexType !== indexType + ? updateNode(createIndexedAccessTypeNode(objectType, indexType), node) + : node; + } + + export function createMappedTypeNode(readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode { + const node = createSynthesizedNode(SyntaxKind.MappedType) as MappedTypeNode; + node.readonlyToken = readonlyToken; + node.typeParameter = typeParameter; + node.questionToken = questionToken; + node.type = type; + return node; + } + + export function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode { + return node.readonlyToken !== readonlyToken + || node.typeParameter !== typeParameter + || node.questionToken !== questionToken + || node.type !== type + ? updateNode(createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), node) + : node; + } + + export function createLiteralTypeNode(literal: Expression) { + const node = createSynthesizedNode(SyntaxKind.LiteralType) as LiteralTypeNode; + node.literal = literal; + return node; + } + + export function updateLiteralTypeNode(node: LiteralTypeNode, literal: Expression) { + return node.literal !== literal + ? updateNode(createLiteralTypeNode(literal), node) + : node; + } + // Binding Patterns export function createObjectBindingPattern(elements: BindingElement[]) { @@ -705,10 +715,7 @@ namespace ts { export function createArrayLiteral(elements?: Expression[], multiLine?: boolean) { const node = createSynthesizedNode(SyntaxKind.ArrayLiteralExpression); node.elements = parenthesizeListElements(createNodeArray(elements)); - if (multiLine) { - node.multiLine = true; - } - + if (multiLine) node.multiLine = true; return node; } @@ -721,9 +728,7 @@ namespace ts { export function createObjectLiteral(properties?: ObjectLiteralElementLike[], multiLine?: boolean) { const node = createSynthesizedNode(SyntaxKind.ObjectLiteralExpression); node.properties = createNodeArray(properties); - if (multiLine) { - node.multiLine = true; - } + if (multiLine) node.multiLine = true; return node; } @@ -773,9 +778,9 @@ namespace ts { } export function updateCall(node: CallExpression, expression: Expression, typeArguments: TypeNode[] | undefined, argumentsArray: Expression[]) { - return expression !== node.expression - || typeArguments !== node.typeArguments - || argumentsArray !== node.arguments + return node.expression !== expression + || node.typeArguments !== typeArguments + || node.arguments !== argumentsArray ? updateNode(createCall(expression, typeArguments, argumentsArray), node) : node; } @@ -1099,6 +1104,19 @@ namespace ts { : node; } + export function createMetaProperty(keywordToken: MetaProperty["keywordToken"], name: Identifier) { + const node = createSynthesizedNode(SyntaxKind.MetaProperty); + node.keywordToken = keywordToken; + node.name = name; + return node; + } + + export function updateMetaProperty(node: MetaProperty, name: Identifier) { + return node.name !== name + ? updateNode(createMetaProperty(node.keywordToken, name), node) + : node; + } + // Misc export function createTemplateSpan(expression: Expression, literal: TemplateMiddle | TemplateTail) { @@ -1115,6 +1133,10 @@ namespace ts { : node; } + export function createSemicolonClassElement() { + return createSynthesizedNode(SyntaxKind.SemicolonClassElement); + } + // Element export function createBlock(statements: Statement[], multiLine?: boolean): Block { @@ -1125,7 +1147,7 @@ namespace ts { } export function updateBlock(node: Block, statements: Statement[]) { - return statements !== node.statements + return node.statements !== statements ? updateNode(createBlock(statements, node.multiLine), node) : node; } @@ -1145,35 +1167,6 @@ namespace ts { : node; } - export function createVariableDeclarationList(declarations: VariableDeclaration[], flags?: NodeFlags) { - const node = createSynthesizedNode(SyntaxKind.VariableDeclarationList); - node.flags |= flags; - node.declarations = createNodeArray(declarations); - return node; - } - - export function updateVariableDeclarationList(node: VariableDeclarationList, declarations: VariableDeclaration[]) { - return node.declarations !== declarations - ? updateNode(createVariableDeclarationList(declarations, node.flags), node) - : node; - } - - export function createVariableDeclaration(name: string | BindingName, type?: TypeNode, initializer?: Expression) { - const node = createSynthesizedNode(SyntaxKind.VariableDeclaration); - node.name = asName(name); - node.type = type; - node.initializer = initializer !== undefined ? parenthesizeExpressionForList(initializer) : undefined; - return node; - } - - export function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined) { - return node.name !== name - || node.type !== type - || node.initializer !== initializer - ? updateNode(createVariableDeclaration(name, type, initializer), node) - : node; - } - export function createEmptyStatement() { return createSynthesizedNode(SyntaxKind.EmptyStatement); } @@ -1392,6 +1385,39 @@ namespace ts { : node; } + export function createDebuggerStatement() { + return createSynthesizedNode(SyntaxKind.DebuggerStatement); + } + + export function createVariableDeclaration(name: string | BindingName, type?: TypeNode, initializer?: Expression) { + const node = createSynthesizedNode(SyntaxKind.VariableDeclaration); + node.name = asName(name); + node.type = type; + node.initializer = initializer !== undefined ? parenthesizeExpressionForList(initializer) : undefined; + return node; + } + + export function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined) { + return node.name !== name + || node.type !== type + || node.initializer !== initializer + ? updateNode(createVariableDeclaration(name, type, initializer), node) + : node; + } + + export function createVariableDeclarationList(declarations: VariableDeclaration[], flags?: NodeFlags) { + const node = createSynthesizedNode(SyntaxKind.VariableDeclarationList); + node.flags |= flags & NodeFlags.BlockScoped; + node.declarations = createNodeArray(declarations); + return node; + } + + export function updateVariableDeclarationList(node: VariableDeclarationList, declarations: VariableDeclaration[]) { + return node.declarations !== declarations + ? updateNode(createVariableDeclarationList(declarations, node.flags), node) + : node; + } + export function createFunctionDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) { const node = createSynthesizedNode(SyntaxKind.FunctionDeclaration); node.decorators = asNodeArray(decorators); @@ -1498,7 +1524,7 @@ namespace ts { export function createModuleDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined, flags?: NodeFlags) { const node = createSynthesizedNode(SyntaxKind.ModuleDeclaration); - node.flags |= flags; + node.flags |= flags & (NodeFlags.Namespace | NodeFlags.NestedNamespace | NodeFlags.GlobalAugmentation); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.name = name; @@ -1539,6 +1565,18 @@ namespace ts { : node; } + export function createNamespaceExportDeclaration(name: string | Identifier) { + const node = createSynthesizedNode(SyntaxKind.NamespaceExportDeclaration); + node.name = asName(name); + return node; + } + + export function updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier) { + return node.name !== name + ? updateNode(createNamespaceExportDeclaration(name), node) + : node; + } + export function createImportEqualsDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | Identifier, moduleReference: ModuleReference) { const node = createSynthesizedNode(SyntaxKind.ImportEqualsDeclaration); node.decorators = asNodeArray(decorators); @@ -1569,7 +1607,8 @@ namespace ts { export function updateImportDeclaration(node: ImportDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression | undefined) { return node.decorators !== decorators || node.modifiers !== modifiers - || node.importClause !== importClause || node.moduleSpecifier !== moduleSpecifier + || node.importClause !== importClause + || node.moduleSpecifier !== moduleSpecifier ? updateNode(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier), node) : node; } @@ -1759,19 +1798,6 @@ namespace ts { : node; } - export function createJsxAttributes(properties: JsxAttributeLike[]) { - const jsxAttributes = createSynthesizedNode(SyntaxKind.JsxAttributes); - jsxAttributes.properties = createNodeArray(properties); - return jsxAttributes; - } - - export function updateJsxAttributes(jsxAttributes: JsxAttributes, properties: JsxAttributeLike[]) { - if (jsxAttributes.properties !== properties) { - return updateNode(createJsxAttributes(properties), jsxAttributes); - } - return jsxAttributes; - } - export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression) { const node = createSynthesizedNode(SyntaxKind.JsxAttribute); node.name = name; @@ -1786,6 +1812,18 @@ namespace ts { : node; } + export function createJsxAttributes(properties: JsxAttributeLike[]) { + const node = createSynthesizedNode(SyntaxKind.JsxAttributes); + node.properties = createNodeArray(properties); + return node; + } + + export function updateJsxAttributes(node: JsxAttributes, properties: JsxAttributeLike[]) { + return node.properties !== properties + ? updateNode(createJsxAttributes(properties), node) + : node; + } + export function createJsxSpreadAttribute(expression: Expression) { const node = createSynthesizedNode(SyntaxKind.JsxSpreadAttribute); node.expression = expression; @@ -1813,20 +1851,6 @@ namespace ts { // Clauses - export function createHeritageClause(token: HeritageClause["token"], types: ExpressionWithTypeArguments[]) { - const node = createSynthesizedNode(SyntaxKind.HeritageClause); - node.token = token; - node.types = createNodeArray(types); - return node; - } - - export function updateHeritageClause(node: HeritageClause, types: ExpressionWithTypeArguments[]) { - if (node.types !== types) { - return updateNode(createHeritageClause(node.token, types), node); - } - return node; - } - export function createCaseClause(expression: Expression, statements: Statement[]) { const node = createSynthesizedNode(SyntaxKind.CaseClause); node.expression = parenthesizeExpressionForList(expression); @@ -1835,10 +1859,10 @@ namespace ts { } export function updateCaseClause(node: CaseClause, expression: Expression, statements: Statement[]) { - if (node.expression !== expression || node.statements !== statements) { - return updateNode(createCaseClause(expression, statements), node); - } - return node; + return node.expression !== expression + || node.statements !== statements + ? updateNode(createCaseClause(expression, statements), node) + : node; } export function createDefaultClause(statements: Statement[]) { @@ -1848,12 +1872,24 @@ namespace ts { } export function updateDefaultClause(node: DefaultClause, statements: Statement[]) { - if (node.statements !== statements) { - return updateNode(createDefaultClause(statements), node); - } + return node.statements !== statements + ? updateNode(createDefaultClause(statements), node) + : node; + } + + export function createHeritageClause(token: HeritageClause["token"], types: ExpressionWithTypeArguments[]) { + const node = createSynthesizedNode(SyntaxKind.HeritageClause); + node.token = token; + node.types = createNodeArray(types); return node; } + export function updateHeritageClause(node: HeritageClause, types: ExpressionWithTypeArguments[]) { + return node.types !== types + ? updateNode(createHeritageClause(node.token, types), node) + : node; + } + export function createCatchClause(variableDeclaration: string | VariableDeclaration, block: Block) { const node = createSynthesizedNode(SyntaxKind.CatchClause); node.variableDeclaration = typeof variableDeclaration === "string" ? createVariableDeclaration(variableDeclaration) : variableDeclaration; @@ -1862,10 +1898,10 @@ namespace ts { } export function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration, block: Block) { - if (node.variableDeclaration !== variableDeclaration || node.block !== block) { - return updateNode(createCatchClause(variableDeclaration, block), node); - } - return node; + return node.variableDeclaration !== variableDeclaration + || node.block !== block + ? updateNode(createCatchClause(variableDeclaration, block), node) + : node; } // Property assignments @@ -1879,10 +1915,10 @@ namespace ts { } export function updatePropertyAssignment(node: PropertyAssignment, name: PropertyName, initializer: Expression) { - if (node.name !== name || node.initializer !== initializer) { - return updateNode(createPropertyAssignment(name, initializer), node); - } - return node; + return node.name !== name + || node.initializer !== initializer + ? updateNode(createPropertyAssignment(name, initializer), node) + : node; } export function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression) { @@ -1893,10 +1929,10 @@ namespace ts { } export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression | undefined) { - if (node.name !== name || node.objectAssignmentInitializer !== objectAssignmentInitializer) { - return updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node); - } - return node; + return node.name !== name + || node.objectAssignmentInitializer !== objectAssignmentInitializer + ? updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node) + : node; } export function createSpreadAssignment(expression: Expression) { @@ -1906,10 +1942,9 @@ namespace ts { } export function updateSpreadAssignment(node: SpreadAssignment, expression: Expression) { - if (node.expression !== expression) { - return updateNode(createSpreadAssignment(expression), node); - } - return node; + return node.expression !== expression + ? updateNode(createSpreadAssignment(expression), node) + : node; } // Enum diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index d511b31b331..f984c12fb68 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -2,7 +2,6 @@ /// namespace ts { - /* @internal */ export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void; export function trace(host: ModuleResolutionHost): void { @@ -15,6 +14,7 @@ namespace ts { } /** Array that is only intended to be pushed to, never read. */ + /* @internal */ export interface Push { push(value: T): void; } @@ -675,12 +675,25 @@ namespace ts { } export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations { - return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, /*jsOnly*/ false); + return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, /*jsOnly*/ false); } + /** + * Expose resolution logic to allow us to use Node module resolution logic from arbitrary locations. + * No way to do this with `require()`: https://github.com/nodejs/node/issues/5963 + * Throws an error if the module can't be resolved. + */ /* @internal */ - export function nodeModuleNameResolverWorker(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, jsOnly = false): ResolvedModuleWithFailedLookupLocations { - const containingDirectory = getDirectoryPath(containingFile); + export function resolveJavaScriptModule(moduleName: string, initialDir: string, host: ModuleResolutionHost): string { + const { resolvedModule, failedLookupLocations } = + nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, /*jsOnly*/ true); + if (!resolvedModule) { + throw new Error(`Could not resolve JS module ${moduleName} starting at ${initialDir}. Looked in: ${failedLookupLocations.join(", ")}`); + } + return resolvedModule.resolvedFileName; + } + + function nodeModuleNameResolverWorker(moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, jsOnly: boolean): ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); const failedLookupLocations: string[] = []; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index d355ff24583..cc3fb24bdb8 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6502,6 +6502,8 @@ namespace ts { case "augments": tag = parseAugmentsTag(atToken, tagName); break; + case "arg": + case "argument": case "param": tag = parseParamTag(atToken, tagName); break; diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index cd3f1310100..ad9a6b99395 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -2009,13 +2009,14 @@ namespace ts { } else { assignment = createBinary(decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression)); + setTextRange(assignment, decl); } assignments = append(assignments, assignment); } } if (assignments) { - updated = setTextRange(createStatement(reduceLeft(assignments, (acc, v) => createBinary(v, SyntaxKind.CommaToken, acc))), node); + updated = setTextRange(createStatement(inlineExpressions(assignments)), node); } else { // none of declarations has initializer - the entire variable statement can be deleted diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 63879d76ffa..a6c04616652 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1508,7 +1508,7 @@ namespace ts { // for the same reasons we treat NewExpression as a PrimaryExpression. export interface MetaProperty extends PrimaryExpression { kind: SyntaxKind.MetaProperty; - keywordToken: SyntaxKind; + keywordToken: SyntaxKind.NewKeyword; name: Identifier; } @@ -2554,6 +2554,7 @@ namespace ts { tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined; getApparentType(type: Type): Type; + /* @internal */ getBaseConstraintOfType(type: Type): Type; /* @internal */ tryFindAmbientModuleWithoutAugmentations(moduleName: string): Symbol; @@ -2736,7 +2737,6 @@ namespace ts { writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; - writeBaseConstructorTypeOfClass(node: ClassLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult; isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult; // Returns the constant value this property access resolves to, or 'undefined' for a non-constant diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 0dc6c92ed2c..b69eb2ef86e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3681,7 +3681,18 @@ namespace ts { || kind === SyntaxKind.GetAccessor || kind === SyntaxKind.SetAccessor || kind === SyntaxKind.IndexSignature - || kind === SyntaxKind.SemicolonClassElement; + || kind === SyntaxKind.SemicolonClassElement + || kind === SyntaxKind.MissingDeclaration; + } + + export function isTypeElement(node: Node): node is TypeElement { + const kind = node.kind; + return kind === SyntaxKind.ConstructSignature + || kind === SyntaxKind.CallSignature + || kind === SyntaxKind.PropertySignature + || kind === SyntaxKind.MethodSignature + || kind === SyntaxKind.IndexSignature + || kind === SyntaxKind.MissingDeclaration; } export function isObjectLiteralElementLike(node: Node): node is ObjectLiteralElementLike { diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 54cea3168e1..e434dadeaf7 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -218,16 +218,7 @@ namespace ts { return node; } - switch (node.kind) { - case SyntaxKind.SemicolonClassElement: - case SyntaxKind.EmptyStatement: - case SyntaxKind.OmittedExpression: - case SyntaxKind.DebuggerStatement: - case SyntaxKind.EndOfDeclarationMarker: - case SyntaxKind.MissingDeclaration: - // No need to visit nodes with no children. - return node; - + switch (kind) { // Names case SyntaxKind.QualifiedName: return updateQualifiedName(node, @@ -238,45 +229,13 @@ namespace ts { return updateComputedPropertyName(node, visitNode((node).expression, visitor, isExpression)); - // Signatures and Signature Elements - case SyntaxKind.FunctionType: - return updateFunctionTypeNode(node, - nodesVisitor((node).typeParameters, visitor, isTypeParameter), - nodesVisitor((node).parameters, visitor, isParameterDeclaration), - visitNode((node).type, visitor, isTypeNode)); + // Signature elements - case SyntaxKind.ConstructorType: - return updateConstructorTypeNode(node, - nodesVisitor((node).typeParameters, visitor, isTypeParameter), - nodesVisitor((node).parameters, visitor, isParameterDeclaration), - visitNode((node).type, visitor, isTypeNode)); - - case SyntaxKind.CallSignature: - return updateCallSignatureDeclaration(node, - nodesVisitor((node).typeParameters, visitor, isTypeParameter), - nodesVisitor((node).parameters, visitor, isParameterDeclaration), - visitNode((node).type, visitor, isTypeNode)); - - case SyntaxKind.ConstructSignature: - return updateConstructSignatureDeclaration(node, - nodesVisitor((node).typeParameters, visitor, isTypeParameter), - nodesVisitor((node).parameters, visitor, isParameterDeclaration), - visitNode((node).type, visitor, isTypeNode)); - - case SyntaxKind.MethodSignature: - return updateMethodSignature(node, - nodesVisitor((node).typeParameters, visitor, isTypeParameter), - nodesVisitor((node).parameters, visitor, isParameterDeclaration), - visitNode((node).type, visitor, isTypeNode), - visitNode((node).name, visitor, isPropertyName), - visitNode((node).questionToken, tokenVisitor, isToken)); - - case SyntaxKind.IndexSignature: - return updateIndexSignatureDeclaration(node, - nodesVisitor((node).decorators, visitor, isDecorator), - nodesVisitor((node).modifiers, visitor, isModifier), - nodesVisitor((node).parameters, visitor, isParameterDeclaration), - visitNode((node).type, visitor, isTypeNode)); + case SyntaxKind.TypeParameter: + return updateTypeParameterDeclaration(node, + visitNode((node).name, visitor, isIdentifier), + visitNode((node).constraint, visitor, isTypeNode), + visitNode((node).default, visitor, isTypeNode)); case SyntaxKind.Parameter: return updateParameter(node, @@ -292,67 +251,7 @@ namespace ts { return updateDecorator(node, visitNode((node).expression, visitor, isExpression)); - // Types - - case SyntaxKind.TypeReference: - return updateTypeReferenceNode(node, - visitNode((node).typeName, visitor, isEntityName), - nodesVisitor((node).typeArguments, visitor, isTypeNode)); - - case SyntaxKind.TypePredicate: - return updateTypePredicateNode(node, - visitNode((node).parameterName, visitor), - visitNode((node).type, visitor, isTypeNode)); - - case SyntaxKind.TypeQuery: - return updateTypeQueryNode((node), visitNode((node).exprName, visitor, isEntityName)); - - case SyntaxKind.TypeLiteral: - return updateTypeLiteralNode((node), nodesVisitor((node).members, visitor)); - - case SyntaxKind.ArrayType: - return updateArrayTypeNode(node, visitNode((node).elementType, visitor, isTypeNode)); - - case SyntaxKind.TupleType: - return updateTypleTypeNode((node), nodesVisitor((node).elementTypes, visitor, isTypeNode)); - - case SyntaxKind.UnionType: - case SyntaxKind.IntersectionType: - return updateUnionOrIntersectionTypeNode(node, - nodesVisitor((node).types, visitor, isTypeNode)); - - case SyntaxKind.ParenthesizedType: - return updateParenthesizedType(node, - visitNode((node).type, visitor, isTypeNode)); - - case SyntaxKind.TypeOperator: - return updateTypeOperatorNode(node, visitNode((node).type, visitor, isTypeNode)); - - case SyntaxKind.IndexedAccessType: - return updateIndexedAccessTypeNode((node), - visitNode((node).objectType, visitor, isTypeNode), - visitNode((node).indexType, visitor, isTypeNode)); - - case SyntaxKind.MappedType: - return updateMappedTypeNode((node), - visitNode((node).readonlyToken, tokenVisitor, isToken), - visitNode((node).typeParameter, visitor, isTypeParameter), - visitNode((node).questionToken, tokenVisitor, isToken), - visitNode((node).type, visitor, isTypeNode)); - - case SyntaxKind.LiteralType: - return updateLiteralTypeNode(node, - visitNode((node).literal, visitor, isExpression)); - - // Type Declarations - - case SyntaxKind.TypeParameter: - return updateTypeParameterDeclaration(node, - visitNode((node).name, visitor, isIdentifier), - visitNode((node).constraint, visitor, isTypeNode), - visitNode((node).default, visitor, isTypeNode)); - - // Type members + // Type elements case SyntaxKind.PropertySignature: return updatePropertySignature((node), @@ -369,6 +268,14 @@ namespace ts { visitNode((node).type, visitor, isTypeNode), visitNode((node).initializer, visitor, isExpression)); + case SyntaxKind.MethodSignature: + return updateMethodSignature(node, + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).parameters, visitor, isParameterDeclaration), + visitNode((node).type, visitor, isTypeNode), + visitNode((node).name, visitor, isPropertyName), + visitNode((node).questionToken, tokenVisitor, isToken)); + case SyntaxKind.MethodDeclaration: return updateMethod(node, nodesVisitor((node).decorators, visitor, isDecorator), @@ -405,7 +312,99 @@ namespace ts { visitParameterList((node).parameters, visitor, context, nodesVisitor), visitFunctionBody((node).body, visitor, context)); + case SyntaxKind.CallSignature: + return updateCallSignature(node, + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).parameters, visitor, isParameterDeclaration), + visitNode((node).type, visitor, isTypeNode)); + + case SyntaxKind.ConstructSignature: + return updateConstructSignature(node, + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).parameters, visitor, isParameterDeclaration), + visitNode((node).type, visitor, isTypeNode)); + + case SyntaxKind.IndexSignature: + return updateIndexSignature(node, + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), + nodesVisitor((node).parameters, visitor, isParameterDeclaration), + visitNode((node).type, visitor, isTypeNode)); + + // Types + + case SyntaxKind.TypePredicate: + return updateTypePredicateNode(node, + visitNode((node).parameterName, visitor), + visitNode((node).type, visitor, isTypeNode)); + + case SyntaxKind.TypeReference: + return updateTypeReferenceNode(node, + visitNode((node).typeName, visitor, isEntityName), + nodesVisitor((node).typeArguments, visitor, isTypeNode)); + + case SyntaxKind.FunctionType: + return updateFunctionTypeNode(node, + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).parameters, visitor, isParameterDeclaration), + visitNode((node).type, visitor, isTypeNode)); + + case SyntaxKind.ConstructorType: + return updateConstructorTypeNode(node, + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).parameters, visitor, isParameterDeclaration), + visitNode((node).type, visitor, isTypeNode)); + + case SyntaxKind.TypeQuery: + return updateTypeQueryNode((node), + visitNode((node).exprName, visitor, isEntityName)); + + case SyntaxKind.TypeLiteral: + return updateTypeLiteralNode((node), + nodesVisitor((node).members, visitor, isTypeElement)); + + case SyntaxKind.ArrayType: + return updateArrayTypeNode(node, + visitNode((node).elementType, visitor, isTypeNode)); + + case SyntaxKind.TupleType: + return updateTypleTypeNode((node), + nodesVisitor((node).elementTypes, visitor, isTypeNode)); + + case SyntaxKind.UnionType: + return updateUnionTypeNode(node, + nodesVisitor((node).types, visitor, isTypeNode)); + + case SyntaxKind.IntersectionType: + return updateIntersectionTypeNode(node, + nodesVisitor((node).types, visitor, isTypeNode)); + + case SyntaxKind.ParenthesizedType: + return updateParenthesizedType(node, + visitNode((node).type, visitor, isTypeNode)); + + case SyntaxKind.TypeOperator: + return updateTypeOperatorNode(node, + visitNode((node).type, visitor, isTypeNode)); + + case SyntaxKind.IndexedAccessType: + return updateIndexedAccessTypeNode((node), + visitNode((node).objectType, visitor, isTypeNode), + visitNode((node).indexType, visitor, isTypeNode)); + + case SyntaxKind.MappedType: + return updateMappedTypeNode((node), + visitNode((node).readonlyToken, tokenVisitor, isToken), + visitNode((node).typeParameter, visitor, isTypeParameter), + visitNode((node).questionToken, tokenVisitor, isToken), + visitNode((node).type, visitor, isTypeNode)); + + case SyntaxKind.LiteralType: + return updateLiteralTypeNode(node, + visitNode((node).literal, visitor, isExpression)); + // Binding patterns + case SyntaxKind.ObjectBindingPattern: return updateObjectBindingPattern(node, nodesVisitor((node).elements, visitor, isBindingElement)); @@ -422,6 +421,7 @@ namespace ts { visitNode((node).initializer, visitor, isExpression)); // Expression + case SyntaxKind.ArrayLiteralExpression: return updateArrayLiteral(node, nodesVisitor((node).elements, visitor, isExpression)); @@ -500,11 +500,6 @@ namespace ts { return updateAwait(node, visitNode((node).expression, visitor, isExpression)); - case SyntaxKind.BinaryExpression: - return updateBinary(node, - visitNode((node).left, visitor, isExpression), - visitNode((node).right, visitor, isExpression)); - case SyntaxKind.PrefixUnaryExpression: return updatePrefix(node, visitNode((node).operand, visitor, isExpression)); @@ -513,6 +508,11 @@ namespace ts { return updatePostfix(node, visitNode((node).operand, visitor, isExpression)); + case SyntaxKind.BinaryExpression: + return updateBinary(node, + visitNode((node).left, visitor, isExpression), + visitNode((node).right, visitor, isExpression)); + case SyntaxKind.ConditionalExpression: return updateConditional(node, visitNode((node).condition, visitor, isExpression), @@ -555,13 +555,19 @@ namespace ts { return updateNonNullExpression(node, visitNode((node).expression, visitor, isExpression)); + case SyntaxKind.MetaProperty: + return updateMetaProperty(node, + visitNode((node).name, visitor, isIdentifier)); + // Misc + case SyntaxKind.TemplateSpan: return updateTemplateSpan(node, visitNode((node).expression, visitor, isExpression), visitNode((node).literal, visitor, isTemplateMiddleOrTemplateTail)); // Element + case SyntaxKind.Block: return updateBlock(node, nodesVisitor((node).statements, visitor, isStatement)); @@ -678,6 +684,21 @@ namespace ts { nodesVisitor((node).heritageClauses, visitor, isHeritageClause), nodesVisitor((node).members, visitor, isClassElement)); + case SyntaxKind.InterfaceDeclaration: + return updateInterfaceDeclaration(node, + nodesVisitor((node).decorators, visitor, isDecorator), + nodesVisitor((node).modifiers, visitor, isModifier), + visitNode((node).name, visitor, isIdentifier), + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).heritageClauses, visitor, isHeritageClause), + nodesVisitor((node).members, visitor, isTypeElement)); + + case SyntaxKind.TypeAliasDeclaration: + return updateTypeAliasDeclaration(node, + visitNode((node).name, visitor, isIdentifier), + nodesVisitor((node).typeParameters, visitor, isTypeParameter), + visitNode((node).type, visitor, isTypeNode)); + case SyntaxKind.EnumDeclaration: return updateEnumDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), @@ -700,6 +721,10 @@ namespace ts { return updateCaseBlock(node, nodesVisitor((node).clauses, visitor, isCaseOrDefaultClause)); + case SyntaxKind.NamespaceExportDeclaration: + return updateNamespaceExportDeclaration(node, + visitNode((node).name, visitor, isIdentifier)); + case SyntaxKind.ImportEqualsDeclaration: return updateImportEqualsDeclaration(node, nodesVisitor((node).decorators, visitor, isDecorator), @@ -755,21 +780,19 @@ namespace ts { visitNode((node).name, visitor, isIdentifier)); // Module references + case SyntaxKind.ExternalModuleReference: return updateExternalModuleReference(node, visitNode((node).expression, visitor, isExpression)); // JSX + case SyntaxKind.JsxElement: return updateJsxElement(node, visitNode((node).openingElement, visitor, isJsxOpeningElement), nodesVisitor((node).children, visitor, isJsxChild), visitNode((node).closingElement, visitor, isJsxClosingElement)); - case SyntaxKind.JsxAttributes: - return updateJsxAttributes(node, - nodesVisitor((node).properties, visitor, isJsxAttributeLike)); - case SyntaxKind.JsxSelfClosingElement: return updateJsxSelfClosingElement(node, visitNode((node).tagName, visitor, isJsxTagNameExpression), @@ -789,6 +812,10 @@ namespace ts { visitNode((node).name, visitor, isIdentifier), visitNode((node).initializer, visitor, isStringLiteralOrJsxExpression)); + case SyntaxKind.JsxAttributes: + return updateJsxAttributes(node, + nodesVisitor((node).properties, visitor, isJsxAttributeLike)); + case SyntaxKind.JsxSpreadAttribute: return updateJsxSpreadAttribute(node, visitNode((node).expression, visitor, isExpression)); @@ -798,6 +825,7 @@ namespace ts { visitNode((node).expression, visitor, isExpression)); // Clauses + case SyntaxKind.CaseClause: return updateCaseClause(node, visitNode((node).expression, visitor, isExpression), @@ -817,6 +845,7 @@ namespace ts { visitNode((node).block, visitor, isBlock)); // Property assignments + case SyntaxKind.PropertyAssignment: return updatePropertyAssignment(node, visitNode((node).name, visitor, isPropertyName), @@ -848,8 +877,10 @@ namespace ts { visitNode((node).expression, visitor, isExpression)); default: + // No need to visit nodes with no children. return node; } + } /** diff --git a/src/harness/unittests/jsDocParsing.ts b/src/harness/unittests/jsDocParsing.ts index 98c32c77778..309e49bd6b8 100644 --- a/src/harness/unittests/jsDocParsing.ts +++ b/src/harness/unittests/jsDocParsing.ts @@ -241,6 +241,18 @@ namespace ts { */`); + parsesCorrectly("argSynonymForParamTag", +`/** + * @arg {number} name1 Description + */`); + + + parsesCorrectly("argumentSynonymForParamTag", +`/** + * @argument {number} name1 Description + */`); + + parsesCorrectly("templateTag", `/** * @template T diff --git a/src/server/server.ts b/src/server/server.ts index 79cfc3882ae..67640e430d8 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -708,12 +708,11 @@ namespace ts.server { } sys.require = (initialDir: string, moduleName: string): RequireResult => { - const result = nodeModuleNameResolverWorker(moduleName, initialDir + "/program.ts", { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, sys, /*cache*/ undefined, /*jsOnly*/ true); try { - return { module: require(result.resolvedModule.resolvedFileName), error: undefined }; + return { module: require(resolveJavaScriptModule(moduleName, initialDir, sys)), error: undefined }; } - catch (e) { - return { module: undefined, error: e }; + catch (error) { + return { module: undefined, error }; } }; diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts index 895a4e17cc7..1182450ce81 100644 --- a/src/server/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts @@ -96,6 +96,9 @@ namespace ts.server.typingsInstaller { this.log.writeLine(`Updating ${TypesRegistryPackageName} npm package...`); } this.execSync(`${this.npmPath} install ${TypesRegistryPackageName}`, { cwd: globalTypingsCacheLocation, stdio: "ignore" }); + if (this.log.isEnabled()) { + this.log.writeLine(`Updated ${TypesRegistryPackageName} npm package`); + } } catch (e) { if (this.log.isEnabled()) { diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 8e1d0ac2f29..5bb24d397d9 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -110,16 +110,16 @@ namespace ts.codefix { if (!isStatic) { const stringTypeNode = createKeywordTypeNode(SyntaxKind.StringKeyword); const indexingParameter = createParameter( - /*decorators*/ undefined, - /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, "x", - /*questionToken*/ undefined, + /*questionToken*/ undefined, stringTypeNode, - /*initializer*/ undefined); - const indexSignature = createIndexSignatureDeclaration( - /*decorators*/ undefined, - /*modifiers*/ undefined, + /*initializer*/ undefined); + const indexSignature = createIndexSignature( + /*decorators*/ undefined, + /*modifiers*/ undefined, [indexingParameter], typeNode); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 6585e994543..957112016c4 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -200,7 +200,7 @@ namespace ts.codefix { } export function createStubbedMethod(modifiers: Modifier[], name: PropertyName, optional: boolean, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], returnType: TypeNode | undefined) { - return createMethodDeclaration( + return createMethod( /*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, diff --git a/src/services/completions.ts b/src/services/completions.ts index b9d62df751e..318c02683ff 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -260,7 +260,7 @@ namespace ts.Completions { function addStringLiteralCompletionsFromType(type: Type, result: Push, typeChecker: TypeChecker): void { if (type && type.flags & TypeFlags.TypeParameter) { - type = typeChecker.getApparentType(type); + type = typeChecker.getBaseConstraintOfType(type); } if (!type) { return; diff --git a/src/services/formatting/tokenRange.ts b/src/services/formatting/tokenRange.ts index 28f22cec475..29855279e25 100644 --- a/src/services/formatting/tokenRange.ts +++ b/src/services/formatting/tokenRange.ts @@ -3,23 +3,13 @@ /* @internal */ namespace ts.formatting { export namespace Shared { - export interface ITokenAccess { - GetTokens(): SyntaxKind[]; - Contains(token: SyntaxKind): boolean; - isSpecific(): boolean; + const allTokens: SyntaxKind[] = []; + for (let token = SyntaxKind.FirstToken; token <= SyntaxKind.LastToken; token++) { + allTokens.push(token); } - export class TokenRangeAccess implements ITokenAccess { - private tokens: SyntaxKind[]; - - constructor(from: SyntaxKind, to: SyntaxKind, except: SyntaxKind[]) { - this.tokens = []; - for (let token = from; token <= to; token++) { - if (ts.indexOf(except, token) < 0) { - this.tokens.push(token); - } - } - } + class TokenValuesAccess implements TokenRange { + constructor(private readonly tokens: SyntaxKind[] = []) { } public GetTokens(): SyntaxKind[] { return this.tokens; @@ -32,27 +22,8 @@ namespace ts.formatting { public isSpecific() { return true; } } - export class TokenValuesAccess implements ITokenAccess { - private tokens: SyntaxKind[]; - - constructor(tks: SyntaxKind[]) { - this.tokens = tks && tks.length ? tks : []; - } - - public GetTokens(): SyntaxKind[] { - return this.tokens; - } - - public Contains(token: SyntaxKind): boolean { - return this.tokens.indexOf(token) >= 0; - } - - public isSpecific() { return true; } - } - - export class TokenSingleValueAccess implements ITokenAccess { - constructor(public token: SyntaxKind) { - } + class TokenSingleValueAccess implements TokenRange { + constructor(private readonly token: SyntaxKind) {} public GetTokens(): SyntaxKind[] { return [this.token]; @@ -65,12 +36,7 @@ namespace ts.formatting { public isSpecific() { return true; } } - const allTokens: SyntaxKind[] = []; - for (let token = SyntaxKind.FirstToken; token <= SyntaxKind.LastToken; token++) { - allTokens.push(token); - } - - export class TokenAllAccess implements ITokenAccess { + class TokenAllAccess implements TokenRange { public GetTokens(): SyntaxKind[] { return allTokens; } @@ -86,8 +52,8 @@ namespace ts.formatting { public isSpecific() { return false; } } - export class TokenAllExceptAccess implements ITokenAccess { - constructor(readonly except: SyntaxKind) {} + class TokenAllExceptAccess implements TokenRange { + constructor(private readonly except: SyntaxKind) {} public GetTokens(): SyntaxKind[] { return allTokens.filter(t => t !== this.except); @@ -100,55 +66,58 @@ namespace ts.formatting { public isSpecific() { return false; } } - export class TokenRange { - constructor(public tokenAccess: ITokenAccess) { + export interface TokenRange { + GetTokens(): SyntaxKind[]; + Contains(token: SyntaxKind): boolean; + isSpecific(): boolean; + } + + export namespace TokenRange { + export function FromToken(token: SyntaxKind): TokenRange { + return new TokenSingleValueAccess(token); } - static FromToken(token: SyntaxKind): TokenRange { - return new TokenRange(new TokenSingleValueAccess(token)); + export function FromTokens(tokens: SyntaxKind[]): TokenRange { + return new TokenValuesAccess(tokens); } - static FromTokens(tokens: SyntaxKind[]): TokenRange { - return new TokenRange(new TokenValuesAccess(tokens)); + export function FromRange(from: SyntaxKind, to: SyntaxKind, except: SyntaxKind[] = []): TokenRange { + const tokens: SyntaxKind[] = []; + for (let token = from; token <= to; token++) { + if (ts.indexOf(except, token) < 0) { + tokens.push(token); + } + } + return new TokenValuesAccess(tokens); } - static FromRange(f: SyntaxKind, to: SyntaxKind, except: SyntaxKind[] = []): TokenRange { - return new TokenRange(new TokenRangeAccess(f, to, except)); + export function AnyExcept(token: SyntaxKind): TokenRange { + return new TokenAllExceptAccess(token); } - static AnyExcept(token: SyntaxKind): TokenRange { - return new TokenRange(new TokenAllExceptAccess(token)); - } - - public GetTokens(): SyntaxKind[] { - return this.tokenAccess.GetTokens(); - } - - public Contains(token: SyntaxKind): boolean { - return this.tokenAccess.Contains(token); - } - - public toString(): string { - return this.tokenAccess.toString(); - } - - public isSpecific() { - return this.tokenAccess.isSpecific(); - } - - static Any: TokenRange = new TokenRange(new TokenAllAccess()); - static AnyIncludingMultilineComments = TokenRange.FromTokens([...allTokens, SyntaxKind.MultiLineCommentTrivia]); - static Keywords = TokenRange.FromRange(SyntaxKind.FirstKeyword, SyntaxKind.LastKeyword); - static BinaryOperators = TokenRange.FromRange(SyntaxKind.FirstBinaryOperator, SyntaxKind.LastBinaryOperator); - static BinaryKeywordOperators = TokenRange.FromTokens([SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword, SyntaxKind.AsKeyword, SyntaxKind.IsKeyword]); - static UnaryPrefixOperators = TokenRange.FromTokens([SyntaxKind.PlusPlusToken, SyntaxKind.MinusMinusToken, SyntaxKind.TildeToken, SyntaxKind.ExclamationToken]); - static UnaryPrefixExpressions = TokenRange.FromTokens([SyntaxKind.NumericLiteral, SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.OpenBraceToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]); - static UnaryPreincrementExpressions = TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]); - static UnaryPostincrementExpressions = TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword]); - static UnaryPredecrementExpressions = TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]); - static UnaryPostdecrementExpressions = TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword]); - static Comments = TokenRange.FromTokens([SyntaxKind.SingleLineCommentTrivia, SyntaxKind.MultiLineCommentTrivia]); - static TypeNames = TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.NumberKeyword, SyntaxKind.StringKeyword, SyntaxKind.BooleanKeyword, SyntaxKind.SymbolKeyword, SyntaxKind.VoidKeyword, SyntaxKind.AnyKeyword]); + export const Any: TokenRange = new TokenAllAccess(); + export const AnyIncludingMultilineComments = TokenRange.FromTokens([...allTokens, SyntaxKind.MultiLineCommentTrivia]); + export const Keywords = TokenRange.FromRange(SyntaxKind.FirstKeyword, SyntaxKind.LastKeyword); + export const BinaryOperators = TokenRange.FromRange(SyntaxKind.FirstBinaryOperator, SyntaxKind.LastBinaryOperator); + export const BinaryKeywordOperators = TokenRange.FromTokens([ + SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword, SyntaxKind.AsKeyword, SyntaxKind.IsKeyword]); + export const UnaryPrefixOperators = TokenRange.FromTokens([ + SyntaxKind.PlusPlusToken, SyntaxKind.MinusMinusToken, SyntaxKind.TildeToken, SyntaxKind.ExclamationToken]); + export const UnaryPrefixExpressions = TokenRange.FromTokens([ + SyntaxKind.NumericLiteral, SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, + SyntaxKind.OpenBraceToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]); + export const UnaryPreincrementExpressions = TokenRange.FromTokens([ + SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]); + export const UnaryPostincrementExpressions = TokenRange.FromTokens([ + SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword]); + export const UnaryPredecrementExpressions = TokenRange.FromTokens([ + SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]); + export const UnaryPostdecrementExpressions = TokenRange.FromTokens([ + SyntaxKind.Identifier, SyntaxKind.CloseParenToken, SyntaxKind.CloseBracketToken, SyntaxKind.NewKeyword]); + export const Comments = TokenRange.FromTokens([SyntaxKind.SingleLineCommentTrivia, SyntaxKind.MultiLineCommentTrivia]); + export const TypeNames = TokenRange.FromTokens([ + SyntaxKind.Identifier, SyntaxKind.NumberKeyword, SyntaxKind.StringKeyword, SyntaxKind.BooleanKeyword, + SyntaxKind.SymbolKeyword, SyntaxKind.VoidKeyword, SyntaxKind.AnyKeyword]); } } } diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 37c22b4352c..4422aab7156 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -28,6 +28,7 @@ namespace ts.JsDoc { "namespace", "param", "private", + "prop", "property", "public", "requires", @@ -38,8 +39,6 @@ namespace ts.JsDoc { "throws", "type", "typedef", - "property", - "prop", "version" ]; let jsDocTagNameCompletionEntries: CompletionEntry[]; diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 7c4f8fb016d..b250ad49467 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -1,168 +1,6 @@ /// /* @internal */ namespace ts.SignatureHelp { - - // A partially written generic type expression is not guaranteed to have the correct syntax tree. the expression could be parsed as less than/greater than expression or a comma expression - // or some other combination depending on what the user has typed so far. For the purposes of signature help we need to consider any location after "<" as a possible generic type reference. - // To do this, the method will back parse the expression starting at the position required. it will try to parse the current expression as a generic type expression, if it did succeed it - // will return the generic identifier that started the expression (e.g. "foo" in "foo { }; + let lambda2 = () => lambda1(len); +} + +//// [capturedVarInLoop.js] +var _loop_1 = function () { + str = 'x', len = str.length; + var lambda1 = function (y) { }; + var lambda2 = function () { return lambda1(len); }; +}; +var str, len; +for (var i = 0; i < 10; i++) { + _loop_1(); +} diff --git a/tests/baselines/reference/capturedVarInLoop.symbols b/tests/baselines/reference/capturedVarInLoop.symbols new file mode 100644 index 00000000000..9f218154fd8 --- /dev/null +++ b/tests/baselines/reference/capturedVarInLoop.symbols @@ -0,0 +1,22 @@ +=== tests/cases/compiler/capturedVarInLoop.ts === +for (var i = 0; i < 10; i++) { +>i : Symbol(i, Decl(capturedVarInLoop.ts, 0, 8)) +>i : Symbol(i, Decl(capturedVarInLoop.ts, 0, 8)) +>i : Symbol(i, Decl(capturedVarInLoop.ts, 0, 8)) + + var str = 'x', len = str.length; +>str : Symbol(str, Decl(capturedVarInLoop.ts, 1, 7)) +>len : Symbol(len, Decl(capturedVarInLoop.ts, 1, 18)) +>str.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>str : Symbol(str, Decl(capturedVarInLoop.ts, 1, 7)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + + let lambda1 = (y) => { }; +>lambda1 : Symbol(lambda1, Decl(capturedVarInLoop.ts, 2, 7)) +>y : Symbol(y, Decl(capturedVarInLoop.ts, 2, 19)) + + let lambda2 = () => lambda1(len); +>lambda2 : Symbol(lambda2, Decl(capturedVarInLoop.ts, 3, 7)) +>lambda1 : Symbol(lambda1, Decl(capturedVarInLoop.ts, 2, 7)) +>len : Symbol(len, Decl(capturedVarInLoop.ts, 1, 18)) +} diff --git a/tests/baselines/reference/capturedVarInLoop.types b/tests/baselines/reference/capturedVarInLoop.types new file mode 100644 index 00000000000..37d78df8ba3 --- /dev/null +++ b/tests/baselines/reference/capturedVarInLoop.types @@ -0,0 +1,30 @@ +=== tests/cases/compiler/capturedVarInLoop.ts === +for (var i = 0; i < 10; i++) { +>i : number +>0 : 0 +>i < 10 : boolean +>i : number +>10 : 10 +>i++ : number +>i : number + + var str = 'x', len = str.length; +>str : string +>'x' : "x" +>len : number +>str.length : number +>str : string +>length : number + + let lambda1 = (y) => { }; +>lambda1 : (y: any) => void +>(y) => { } : (y: any) => void +>y : any + + let lambda2 = () => lambda1(len); +>lambda2 : () => void +>() => lambda1(len) : () => void +>lambda1(len) : void +>lambda1 : (y: any) => void +>len : number +} diff --git a/tests/baselines/reference/checkIndexConstraintOfJavascriptClassExpression.errors.txt b/tests/baselines/reference/checkIndexConstraintOfJavascriptClassExpression.errors.txt new file mode 100644 index 00000000000..d90e6d506ff --- /dev/null +++ b/tests/baselines/reference/checkIndexConstraintOfJavascriptClassExpression.errors.txt @@ -0,0 +1,29 @@ +tests/cases/compiler/weird.js(1,1): error TS2304: Cannot find name 'someFunction'. +tests/cases/compiler/weird.js(1,23): error TS7006: Parameter 'BaseClass' implicitly has an 'any' type. +tests/cases/compiler/weird.js(6,13): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/compiler/weird.js(9,17): error TS7006: Parameter 'error' implicitly has an 'any' type. + + +==== tests/cases/compiler/weird.js (4 errors) ==== + someFunction(function(BaseClass) { + ~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'someFunction'. + ~~~~~~~~~ +!!! error TS7006: Parameter 'BaseClass' implicitly has an 'any' type. + 'use strict'; + const DEFAULT_MESSAGE = "nop!"; + class Hello extends BaseClass { + constructor() { + super(); + ~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + this.foo = "bar"; + } + _render(error) { + ~~~~~ +!!! error TS7006: Parameter 'error' implicitly has an 'any' type. + const message = error.message || DEFAULT_MESSAGE; + } + } + }); + \ No newline at end of file diff --git a/tests/baselines/reference/checkIndexConstraintOfJavascriptClassExpression.js b/tests/baselines/reference/checkIndexConstraintOfJavascriptClassExpression.js deleted file mode 100644 index a23461a1b58..00000000000 --- a/tests/baselines/reference/checkIndexConstraintOfJavascriptClassExpression.js +++ /dev/null @@ -1,32 +0,0 @@ -//// [weird.js] -someFunction(function(BaseClass) { - class Hello extends BaseClass { - constructor() { - this.foo = "bar"; - } - } -}); - - -//// [foo.js] -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -someFunction(function (BaseClass) { - var Hello = (function (_super) { - __extends(Hello, _super); - function Hello() { - var _this = this; - _this.foo = "bar"; - return _this; - } - return Hello; - }(BaseClass)); -}); diff --git a/tests/baselines/reference/checkJsxChildrenProperty12.js b/tests/baselines/reference/checkJsxChildrenProperty12.js new file mode 100644 index 00000000000..0030d87483f --- /dev/null +++ b/tests/baselines/reference/checkJsxChildrenProperty12.js @@ -0,0 +1,76 @@ +//// [file.tsx] +import React = require('react'); + +interface ButtonProp { + a: number, + b: string, + children: Button; +} + +class Button extends React.Component { + render() { + let condition: boolean; + if (condition) { + return + } + else { + return ( +
Hello World
+
); + } + } +} + +interface InnerButtonProp { + a: number +} + +class InnerButton extends React.Component { + render() { + return (); + } +} + + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +var React = require("react"); +var Button = (function (_super) { + __extends(Button, _super); + function Button() { + return _super !== null && _super.apply(this, arguments) || this; + } + Button.prototype.render = function () { + var condition; + if (condition) { + return ; + } + else { + return ( +
Hello World
+
); + } + }; + return Button; +}(React.Component)); +var InnerButton = (function (_super) { + __extends(InnerButton, _super); + function InnerButton() { + return _super !== null && _super.apply(this, arguments) || this; + } + InnerButton.prototype.render = function () { + return (); + }; + return InnerButton; +}(React.Component)); diff --git a/tests/baselines/reference/checkJsxChildrenProperty12.symbols b/tests/baselines/reference/checkJsxChildrenProperty12.symbols new file mode 100644 index 00000000000..ccfb4b18875 --- /dev/null +++ b/tests/baselines/reference/checkJsxChildrenProperty12.symbols @@ -0,0 +1,80 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +interface ButtonProp { +>ButtonProp : Symbol(ButtonProp, Decl(file.tsx, 0, 32)) + + a: number, +>a : Symbol(ButtonProp.a, Decl(file.tsx, 2, 22)) + + b: string, +>b : Symbol(ButtonProp.b, Decl(file.tsx, 3, 14)) + + children: Button; +>children : Symbol(ButtonProp.children, Decl(file.tsx, 4, 14)) +>Button : Symbol(Button, Decl(file.tsx, 6, 1)) +} + +class Button extends React.Component { +>Button : Symbol(Button, Decl(file.tsx, 6, 1)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>ButtonProp : Symbol(ButtonProp, Decl(file.tsx, 0, 32)) + + render() { +>render : Symbol(Button.render, Decl(file.tsx, 8, 55)) + + let condition: boolean; +>condition : Symbol(condition, Decl(file.tsx, 10, 5)) + + if (condition) { +>condition : Symbol(condition, Decl(file.tsx, 10, 5)) + + return +>InnerButton : Symbol(InnerButton, Decl(file.tsx, 24, 1)) +>this.props : Symbol(React.Component.props, Decl(react.d.ts, 166, 37)) +>this : Symbol(Button, Decl(file.tsx, 6, 1)) +>props : Symbol(React.Component.props, Decl(react.d.ts, 166, 37)) + } + else { + return ( +>InnerButton : Symbol(InnerButton, Decl(file.tsx, 24, 1)) +>this.props : Symbol(React.Component.props, Decl(react.d.ts, 166, 37)) +>this : Symbol(Button, Decl(file.tsx, 6, 1)) +>props : Symbol(React.Component.props, Decl(react.d.ts, 166, 37)) + +
Hello World
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react.d.ts, 2399, 45)) + +
); +>InnerButton : Symbol(InnerButton, Decl(file.tsx, 24, 1)) + } + } +} + +interface InnerButtonProp { +>InnerButtonProp : Symbol(InnerButtonProp, Decl(file.tsx, 20, 1)) + + a: number +>a : Symbol(InnerButtonProp.a, Decl(file.tsx, 22, 27)) +} + +class InnerButton extends React.Component { +>InnerButton : Symbol(InnerButton, Decl(file.tsx, 24, 1)) +>React.Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>React : Symbol(React, Decl(file.tsx, 0, 0)) +>Component : Symbol(React.Component, Decl(react.d.ts, 158, 55)) +>InnerButtonProp : Symbol(InnerButtonProp, Decl(file.tsx, 20, 1)) + + render() { +>render : Symbol(InnerButton.render, Decl(file.tsx, 26, 65)) + + return (); +>button : Symbol(JSX.IntrinsicElements.button, Decl(react.d.ts, 2385, 43)) +>button : Symbol(JSX.IntrinsicElements.button, Decl(react.d.ts, 2385, 43)) + } +} + diff --git a/tests/baselines/reference/checkJsxChildrenProperty12.types b/tests/baselines/reference/checkJsxChildrenProperty12.types new file mode 100644 index 00000000000..93a7d0f9be1 --- /dev/null +++ b/tests/baselines/reference/checkJsxChildrenProperty12.types @@ -0,0 +1,86 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : typeof React + +interface ButtonProp { +>ButtonProp : ButtonProp + + a: number, +>a : number + + b: string, +>b : string + + children: Button; +>children : Button +>Button : Button +} + +class Button extends React.Component { +>Button : Button +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>ButtonProp : ButtonProp + + render() { +>render : () => JSX.Element + + let condition: boolean; +>condition : boolean + + if (condition) { +>condition : boolean + + return +> : JSX.Element +>InnerButton : typeof InnerButton +>this.props : ButtonProp & { children?: React.ReactNode; } +>this : this +>props : ButtonProp & { children?: React.ReactNode; } + } + else { + return ( +>(
Hello World
) : JSX.Element +>
Hello World
: JSX.Element +>InnerButton : typeof InnerButton +>this.props : ButtonProp & { children?: React.ReactNode; } +>this : this +>props : ButtonProp & { children?: React.ReactNode; } + +
Hello World
+>
Hello World
: JSX.Element +>div : any +>div : any + +
); +>InnerButton : typeof InnerButton + } + } +} + +interface InnerButtonProp { +>InnerButtonProp : InnerButtonProp + + a: number +>a : number +} + +class InnerButton extends React.Component { +>InnerButton : InnerButton +>React.Component : React.Component +>React : typeof React +>Component : typeof React.Component +>InnerButtonProp : InnerButtonProp + + render() { +>render : () => JSX.Element + + return (); +>() : JSX.Element +> : JSX.Element +>button : any +>button : any + } +} + diff --git a/tests/baselines/reference/checkJsxChildrenProperty13.errors.txt b/tests/baselines/reference/checkJsxChildrenProperty13.errors.txt new file mode 100644 index 00000000000..c926980cab1 --- /dev/null +++ b/tests/baselines/reference/checkJsxChildrenProperty13.errors.txt @@ -0,0 +1,33 @@ +tests/cases/conformance/jsx/file.tsx(12,30): error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten. + + +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== + import React = require('react'); + + interface ButtonProp { + a: number, + b: string, + children: Button; + } + + class Button extends React.Component { + render() { + // Error children are specified twice + return ( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten. +
Hello World
+
); + } + } + + interface InnerButtonProp { + a: number + } + + class InnerButton extends React.Component { + render() { + return (); + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/checkJsxChildrenProperty13.js b/tests/baselines/reference/checkJsxChildrenProperty13.js new file mode 100644 index 00000000000..8947e6b211f --- /dev/null +++ b/tests/baselines/reference/checkJsxChildrenProperty13.js @@ -0,0 +1,66 @@ +//// [file.tsx] +import React = require('react'); + +interface ButtonProp { + a: number, + b: string, + children: Button; +} + +class Button extends React.Component { + render() { + // Error children are specified twice + return ( +
Hello World
+
); + } +} + +interface InnerButtonProp { + a: number +} + +class InnerButton extends React.Component { + render() { + return (); + } +} + + +//// [file.jsx] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +var React = require("react"); +var Button = (function (_super) { + __extends(Button, _super); + function Button() { + return _super !== null && _super.apply(this, arguments) || this; + } + Button.prototype.render = function () { + // Error children are specified twice + return ( +
Hello World
+
); + }; + return Button; +}(React.Component)); +var InnerButton = (function (_super) { + __extends(InnerButton, _super); + function InnerButton() { + return _super !== null && _super.apply(this, arguments) || this; + } + InnerButton.prototype.render = function () { + return (); + }; + return InnerButton; +}(React.Component)); diff --git a/tests/baselines/reference/checkJsxChildrenProperty2.errors.txt b/tests/baselines/reference/checkJsxChildrenProperty2.errors.txt index 6bb91bd6385..aeeceb8652e 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty2.errors.txt +++ b/tests/baselines/reference/checkJsxChildrenProperty2.errors.txt @@ -2,7 +2,6 @@ tests/cases/conformance/jsx/file.tsx(14,15): error TS2322: Type '{ a: 10; b: "hi Type '{ a: 10; b: "hi"; }' is not assignable to type 'Prop'. Property 'children' is missing in type '{ a: 10; b: "hi"; }'. tests/cases/conformance/jsx/file.tsx(17,11): error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten. -tests/cases/conformance/jsx/file.tsx(25,11): error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten. tests/cases/conformance/jsx/file.tsx(31,11): error TS2322: Type '{ a: 10; b: "hi"; children: (Element | ((name: string) => Element))[]; }' is not assignable to type 'IntrinsicAttributes & Prop'. Type '{ a: 10; b: "hi"; children: (Element | ((name: string) => Element))[]; }' is not assignable to type 'Prop'. Types of property 'children' are incompatible. @@ -29,7 +28,7 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ a: 10; b: "hi Property 'type' is missing in type 'Element[]'. -==== tests/cases/conformance/jsx/file.tsx (7 errors) ==== +==== tests/cases/conformance/jsx/file.tsx (6 errors) ==== import React = require('react'); interface Prop { @@ -61,8 +60,6 @@ tests/cases/conformance/jsx/file.tsx(49,11): error TS2322: Type '{ a: 10; b: "hi } let k1 = - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten. hi hi hi! ; diff --git a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt index 28c550ccda1..ccf56532bc4 100644 --- a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt +++ b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt @@ -1,15 +1,13 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(27,24): error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. - Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. + Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'LinkProps'. + Property 'goTo' is missing in type '{ extra: true; onClick: (k: "left" | "right") => void; }'. tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(28,24): error TS2322: Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. - Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'. -tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(29,24): error TS2322: Type '{ extra: true; goTo: "home"; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. - Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. -tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(30,24): error TS2322: Type '{ goTo: "home"; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. - Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. -tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(33,25): error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. - Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. -tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(36,25): error TS2322: Type '{ extra: true; goTo: "home"; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. - Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. + Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'LinkProps'. + Property 'goTo' is missing in type '{ onClick: (k: "left" | "right") => void; extra: true; }'. +tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(29,43): error TS2339: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. +tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(30,36): error TS2339: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. +tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(33,65): error TS2339: Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. +tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(36,44): error TS2339: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. ==== tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx (6 errors) ==== @@ -42,29 +40,27 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(36,25): err const b0 = {console.log(k)}}} extra />; // k has type "left" | "right" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. -!!! error TS2322: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. +!!! error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'LinkProps'. +!!! error TS2322: Property 'goTo' is missing in type '{ extra: true; onClick: (k: "left" | "right") => void; }'. const b2 = {console.log(k)}} extra />; // k has type "left" | "right" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. -!!! error TS2322: Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'. +!!! error TS2322: Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'LinkProps'. +!!! error TS2322: Property 'goTo' is missing in type '{ onClick: (k: "left" | "right") => void; extra: true; }'. const b3 = ; // goTo has type"home" | "contact" - ~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ extra: true; goTo: "home"; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. -!!! error TS2322: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. + ~~~~~ +!!! error TS2339: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. const b4 = ; // goTo has type "home" | "contact" - ~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ goTo: "home"; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. -!!! error TS2322: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. + ~~~~~ +!!! error TS2339: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. export function NoOverload(buttonProps: ButtonProps): JSX.Element { return undefined } const c1 = {console.log(k)}}} extra />; // k has type any - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. -!!! error TS2322: Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. + ~~~~~ +!!! error TS2339: Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. export function NoOverload1(linkProps: LinkProps): JSX.Element { return undefined } const d1 = ; // goTo has type "home" | "contact" - ~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ extra: true; goTo: "home"; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. -!!! error TS2322: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. + ~~~~~ +!!! error TS2339: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitDefaultExport5.js b/tests/baselines/reference/declarationEmitDefaultExport5.js index 701318b14d7..427463be5ab 100644 --- a/tests/baselines/reference/declarationEmitDefaultExport5.js +++ b/tests/baselines/reference/declarationEmitDefaultExport5.js @@ -7,5 +7,5 @@ export default 1 + 2; //// [declarationEmitDefaultExport5.d.ts] -declare var _default: number; +declare const _default: number; export default _default; diff --git a/tests/baselines/reference/declarationEmitDefaultExport6.js b/tests/baselines/reference/declarationEmitDefaultExport6.js index d56609e8534..1391ec0b4f2 100644 --- a/tests/baselines/reference/declarationEmitDefaultExport6.js +++ b/tests/baselines/reference/declarationEmitDefaultExport6.js @@ -12,5 +12,5 @@ export default new A(); //// [declarationEmitDefaultExport6.d.ts] export declare class A { } -declare var _default: A; +declare const _default: A; export default _default; diff --git a/tests/baselines/reference/declarationEmitDefaultExport8.js b/tests/baselines/reference/declarationEmitDefaultExport8.js index 5511c5981e5..33ef87bf744 100644 --- a/tests/baselines/reference/declarationEmitDefaultExport8.js +++ b/tests/baselines/reference/declarationEmitDefaultExport8.js @@ -13,5 +13,5 @@ export default 1 + 2; //// [declarationEmitDefaultExport8.d.ts] declare var _default: number; export { _default as d }; -declare var _default_1: number; +declare const _default_1: number; export default _default_1; diff --git a/tests/baselines/reference/declarationEmitDefaultExportWithTempVarName.js b/tests/baselines/reference/declarationEmitDefaultExportWithTempVarName.js index 44e0560132f..11fddc855b2 100644 --- a/tests/baselines/reference/declarationEmitDefaultExportWithTempVarName.js +++ b/tests/baselines/reference/declarationEmitDefaultExportWithTempVarName.js @@ -15,5 +15,5 @@ System.register([], function (exports_1, context_1) { //// [pi.d.ts] -declare var _default: 3.14159; +declare const _default: 3.14159; export default _default; diff --git a/tests/baselines/reference/declarationEmitDefaultExportWithTempVarNameWithBundling.js b/tests/baselines/reference/declarationEmitDefaultExportWithTempVarNameWithBundling.js index 6ac6cf29018..31749d1773e 100644 --- a/tests/baselines/reference/declarationEmitDefaultExportWithTempVarNameWithBundling.js +++ b/tests/baselines/reference/declarationEmitDefaultExportWithTempVarNameWithBundling.js @@ -16,6 +16,6 @@ System.register("pi", [], function (exports_1, context_1) { //// [app.d.ts] declare module "pi" { - var _default: 3.14159; + const _default: 3.14159; export default _default; } diff --git a/tests/baselines/reference/declarationEmitExpressionInExtends2.js b/tests/baselines/reference/declarationEmitExpressionInExtends2.js index 301d935a1db..a49175a3dc4 100644 --- a/tests/baselines/reference/declarationEmitExpressionInExtends2.js +++ b/tests/baselines/reference/declarationEmitExpressionInExtends2.js @@ -45,5 +45,6 @@ declare class C { y: U; } declare function getClass(c: T): typeof C; -declare class MyClass extends C { +declare const MyClass_base: typeof C; +declare class MyClass extends MyClass_base { } diff --git a/tests/baselines/reference/declarationEmitExpressionInExtends3.errors.txt b/tests/baselines/reference/declarationEmitExpressionInExtends3.errors.txt index 636085215ac..4864a3bcdc2 100644 --- a/tests/baselines/reference/declarationEmitExpressionInExtends3.errors.txt +++ b/tests/baselines/reference/declarationEmitExpressionInExtends3.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/declarationEmitExpressionInExtends3.ts(28,30): error TS4020: 'extends' clause of exported class 'MyClass' has or is using private name 'LocalClass'. -tests/cases/compiler/declarationEmitExpressionInExtends3.ts(36,31): error TS4020: 'extends' clause of exported class 'MyClass3' has or is using private name 'LocalInterface'. +tests/cases/compiler/declarationEmitExpressionInExtends3.ts(36,75): error TS4020: 'extends' clause of exported class 'MyClass3' has or is using private name 'LocalInterface'. ==== tests/cases/compiler/declarationEmitExpressionInExtends3.ts (2 errors) ==== @@ -41,7 +41,7 @@ tests/cases/compiler/declarationEmitExpressionInExtends3.ts(36,31): error TS4020 export class MyClass3 extends getExportedClass(undefined) { // Error LocalInterface is inaccisble - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~ !!! error TS4020: 'extends' clause of exported class 'MyClass3' has or is using private name 'LocalInterface'. } diff --git a/tests/baselines/reference/declarationEmitExpressionInExtends4.errors.txt b/tests/baselines/reference/declarationEmitExpressionInExtends4.errors.txt index b2e3eb58d54..54905212836 100644 --- a/tests/baselines/reference/declarationEmitExpressionInExtends4.errors.txt +++ b/tests/baselines/reference/declarationEmitExpressionInExtends4.errors.txt @@ -1,13 +1,12 @@ tests/cases/compiler/declarationEmitExpressionInExtends4.ts(1,10): error TS4060: Return type of exported function has or is using private name 'D'. -tests/cases/compiler/declarationEmitExpressionInExtends4.ts(5,7): error TS4093: 'extends' clause of exported class 'C' refers to a type whose name cannot be referenced. tests/cases/compiler/declarationEmitExpressionInExtends4.ts(5,17): error TS2315: Type 'D' is not generic. -tests/cases/compiler/declarationEmitExpressionInExtends4.ts(9,7): error TS4093: 'extends' clause of exported class 'C2' refers to a type whose name cannot be referenced. +tests/cases/compiler/declarationEmitExpressionInExtends4.ts(5,17): error TS4020: 'extends' clause of exported class 'C' has or is using private name 'D'. tests/cases/compiler/declarationEmitExpressionInExtends4.ts(9,18): error TS2304: Cannot find name 'SomeUndefinedFunction'. tests/cases/compiler/declarationEmitExpressionInExtends4.ts(14,18): error TS2304: Cannot find name 'SomeUndefinedFunction'. tests/cases/compiler/declarationEmitExpressionInExtends4.ts(14,18): error TS4020: 'extends' clause of exported class 'C3' has or is using private name 'SomeUndefinedFunction'. -==== tests/cases/compiler/declarationEmitExpressionInExtends4.ts (7 errors) ==== +==== tests/cases/compiler/declarationEmitExpressionInExtends4.ts (6 errors) ==== function getSomething() { ~~~~~~~~~~~~ !!! error TS4060: Return type of exported function has or is using private name 'D'. @@ -15,16 +14,14 @@ tests/cases/compiler/declarationEmitExpressionInExtends4.ts(14,18): error TS4020 } class C extends getSomething() { - ~ -!!! error TS4093: 'extends' clause of exported class 'C' refers to a type whose name cannot be referenced. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2315: Type 'D' is not generic. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS4020: 'extends' clause of exported class 'C' has or is using private name 'D'. } class C2 extends SomeUndefinedFunction() { - ~~ -!!! error TS4093: 'extends' clause of exported class 'C2' refers to a type whose name cannot be referenced. ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2304: Cannot find name 'SomeUndefinedFunction'. diff --git a/tests/baselines/reference/declarationEmitInferedDefaultExportType.js b/tests/baselines/reference/declarationEmitInferedDefaultExportType.js index 4d9eb47641a..a9eca8d1161 100644 --- a/tests/baselines/reference/declarationEmitInferedDefaultExportType.js +++ b/tests/baselines/reference/declarationEmitInferedDefaultExportType.js @@ -18,7 +18,7 @@ exports["default"] = { //// [declarationEmitInferedDefaultExportType.d.ts] -declare var _default: { +declare const _default: { foo: any[]; bar: any; baz: any; diff --git a/tests/baselines/reference/declarationEmitInferedDefaultExportType2.js b/tests/baselines/reference/declarationEmitInferedDefaultExportType2.js index 96c16829d7e..fde31605659 100644 --- a/tests/baselines/reference/declarationEmitInferedDefaultExportType2.js +++ b/tests/baselines/reference/declarationEmitInferedDefaultExportType2.js @@ -16,7 +16,7 @@ module.exports = { //// [declarationEmitInferedDefaultExportType2.d.ts] -declare var _default: { +declare const _default: { foo: any[]; bar: any; baz: any; diff --git a/tests/baselines/reference/es5ExportDefaultExpression.js b/tests/baselines/reference/es5ExportDefaultExpression.js index 3db562da647..b365018b2f3 100644 --- a/tests/baselines/reference/es5ExportDefaultExpression.js +++ b/tests/baselines/reference/es5ExportDefaultExpression.js @@ -9,5 +9,5 @@ exports.default = (1 + 2); //// [es5ExportDefaultExpression.d.ts] -declare var _default: number; +declare const _default: number; export default _default; diff --git a/tests/baselines/reference/es6ExportDefaultExpression.js b/tests/baselines/reference/es6ExportDefaultExpression.js index ce6dcd71b90..059aae49598 100644 --- a/tests/baselines/reference/es6ExportDefaultExpression.js +++ b/tests/baselines/reference/es6ExportDefaultExpression.js @@ -7,5 +7,5 @@ export default (1 + 2); //// [es6ExportDefaultExpression.d.ts] -declare var _default: number; +declare const _default: number; export default _default; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport.js index bccb0a9dea4..a5b7700c36c 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport.js @@ -48,6 +48,6 @@ var x1 = es6ImportDefaultBindingFollowedWithNamedImport_0_5.m; export declare var a: number; export declare var x: number; export declare var m: number; -declare var _default: {}; +declare const _default: {}; export default _default; //// [es6ImportDefaultBindingFollowedWithNamedImport_1.d.ts] diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportWithExport.js b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportWithExport.js index 756ae6a999b..ff8c1059ad1 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportWithExport.js +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportWithExport.js @@ -47,7 +47,7 @@ define(["require", "exports", "server", "server", "server", "server", "server"], export declare var a: number; export declare var x: number; export declare var m: number; -declare var _default: {}; +declare const _default: {}; export default _default; //// [client.d.ts] export declare var x1: number; diff --git a/tests/baselines/reference/exportClassExtendingIntersection.errors.txt b/tests/baselines/reference/exportClassExtendingIntersection.errors.txt deleted file mode 100644 index eb94869fdc2..00000000000 --- a/tests/baselines/reference/exportClassExtendingIntersection.errors.txt +++ /dev/null @@ -1,39 +0,0 @@ -tests/cases/compiler/FinalClass.ts(4,14): error TS4093: 'extends' clause of exported class 'MyExtendedClass' refers to a type whose name cannot be referenced. - - -==== tests/cases/compiler/BaseClass.ts (0 errors) ==== - export type Constructor = new (...args: any[]) => T; - - export class MyBaseClass { - baseProperty: string; - constructor(value: T) {} - } -==== tests/cases/compiler/MixinClass.ts (0 errors) ==== - import { Constructor, MyBaseClass } from './BaseClass'; - - export interface MyMixin { - mixinProperty: string; - } - - export function MyMixin>>(base: T): T & Constructor { - return class extends base { - mixinProperty: string; - } - } -==== tests/cases/compiler/FinalClass.ts (1 errors) ==== - import { MyBaseClass } from './BaseClass'; - import { MyMixin } from './MixinClass'; - - export class MyExtendedClass extends MyMixin(MyBaseClass) { - ~~~~~~~~~~~~~~~ -!!! error TS4093: 'extends' clause of exported class 'MyExtendedClass' refers to a type whose name cannot be referenced. - extendedClassProperty: number; - } -==== tests/cases/compiler/Main.ts (0 errors) ==== - import { MyExtendedClass } from './FinalClass'; - import { MyMixin } from './MixinClass'; - - const myExtendedClass = new MyExtendedClass('string'); - - const AnotherMixedClass = MyMixin(MyExtendedClass); - \ No newline at end of file diff --git a/tests/baselines/reference/exportClassExtendingIntersection.js b/tests/baselines/reference/exportClassExtendingIntersection.js index 2309a9af9b6..919f1695093 100644 --- a/tests/baselines/reference/exportClassExtendingIntersection.js +++ b/tests/baselines/reference/exportClassExtendingIntersection.js @@ -111,4 +111,11 @@ export interface MyMixin { mixinProperty: string; } export declare function MyMixin>>(base: T): T & Constructor; +//// [FinalClass.d.ts] +import { MyBaseClass } from './BaseClass'; +import { MyMixin } from './MixinClass'; +declare const MyExtendedClass_base: typeof MyBaseClass & (new (...args: any[]) => MyMixin); +export declare class MyExtendedClass extends MyExtendedClass_base { + extendedClassProperty: number; +} //// [Main.d.ts] diff --git a/tests/baselines/reference/exportClassExtendingIntersection.symbols b/tests/baselines/reference/exportClassExtendingIntersection.symbols new file mode 100644 index 00000000000..b22febb7d72 --- /dev/null +++ b/tests/baselines/reference/exportClassExtendingIntersection.symbols @@ -0,0 +1,79 @@ +=== tests/cases/compiler/BaseClass.ts === +export type Constructor = new (...args: any[]) => T; +>Constructor : Symbol(Constructor, Decl(BaseClass.ts, 0, 0)) +>T : Symbol(T, Decl(BaseClass.ts, 0, 24)) +>args : Symbol(args, Decl(BaseClass.ts, 0, 34)) +>T : Symbol(T, Decl(BaseClass.ts, 0, 24)) + +export class MyBaseClass { +>MyBaseClass : Symbol(MyBaseClass, Decl(BaseClass.ts, 0, 55)) +>T : Symbol(T, Decl(BaseClass.ts, 2, 25)) + + baseProperty: string; +>baseProperty : Symbol(MyBaseClass.baseProperty, Decl(BaseClass.ts, 2, 29)) + + constructor(value: T) {} +>value : Symbol(value, Decl(BaseClass.ts, 4, 16)) +>T : Symbol(T, Decl(BaseClass.ts, 2, 25)) +} +=== tests/cases/compiler/MixinClass.ts === +import { Constructor, MyBaseClass } from './BaseClass'; +>Constructor : Symbol(Constructor, Decl(MixinClass.ts, 0, 8)) +>MyBaseClass : Symbol(MyBaseClass, Decl(MixinClass.ts, 0, 21)) + +export interface MyMixin { +>MyMixin : Symbol(MyMixin, Decl(MixinClass.ts, 0, 55), Decl(MixinClass.ts, 4, 1)) + + mixinProperty: string; +>mixinProperty : Symbol(MyMixin.mixinProperty, Decl(MixinClass.ts, 2, 26)) +} + +export function MyMixin>>(base: T): T & Constructor { +>MyMixin : Symbol(MyMixin, Decl(MixinClass.ts, 0, 55), Decl(MixinClass.ts, 4, 1)) +>T : Symbol(T, Decl(MixinClass.ts, 6, 24)) +>Constructor : Symbol(Constructor, Decl(MixinClass.ts, 0, 8)) +>MyBaseClass : Symbol(MyBaseClass, Decl(MixinClass.ts, 0, 21)) +>base : Symbol(base, Decl(MixinClass.ts, 6, 65)) +>T : Symbol(T, Decl(MixinClass.ts, 6, 24)) +>T : Symbol(T, Decl(MixinClass.ts, 6, 24)) +>Constructor : Symbol(Constructor, Decl(MixinClass.ts, 0, 8)) +>MyMixin : Symbol(MyMixin, Decl(MixinClass.ts, 0, 55), Decl(MixinClass.ts, 4, 1)) + + return class extends base { +>base : Symbol(base, Decl(MixinClass.ts, 6, 65)) + + mixinProperty: string; +>mixinProperty : Symbol((Anonymous class).mixinProperty, Decl(MixinClass.ts, 7, 31)) + } +} +=== tests/cases/compiler/FinalClass.ts === +import { MyBaseClass } from './BaseClass'; +>MyBaseClass : Symbol(MyBaseClass, Decl(FinalClass.ts, 0, 8)) + +import { MyMixin } from './MixinClass'; +>MyMixin : Symbol(MyMixin, Decl(FinalClass.ts, 1, 8)) + +export class MyExtendedClass extends MyMixin(MyBaseClass) { +>MyExtendedClass : Symbol(MyExtendedClass, Decl(FinalClass.ts, 1, 39)) +>MyMixin : Symbol(MyMixin, Decl(FinalClass.ts, 1, 8)) +>MyBaseClass : Symbol(MyBaseClass, Decl(FinalClass.ts, 0, 8)) + + extendedClassProperty: number; +>extendedClassProperty : Symbol(MyExtendedClass.extendedClassProperty, Decl(FinalClass.ts, 3, 67)) +} +=== tests/cases/compiler/Main.ts === +import { MyExtendedClass } from './FinalClass'; +>MyExtendedClass : Symbol(MyExtendedClass, Decl(Main.ts, 0, 8)) + +import { MyMixin } from './MixinClass'; +>MyMixin : Symbol(MyMixin, Decl(Main.ts, 1, 8)) + +const myExtendedClass = new MyExtendedClass('string'); +>myExtendedClass : Symbol(myExtendedClass, Decl(Main.ts, 3, 5)) +>MyExtendedClass : Symbol(MyExtendedClass, Decl(Main.ts, 0, 8)) + +const AnotherMixedClass = MyMixin(MyExtendedClass); +>AnotherMixedClass : Symbol(AnotherMixedClass, Decl(Main.ts, 5, 5)) +>MyMixin : Symbol(MyMixin, Decl(Main.ts, 1, 8)) +>MyExtendedClass : Symbol(MyExtendedClass, Decl(Main.ts, 0, 8)) + diff --git a/tests/baselines/reference/exportClassExtendingIntersection.types b/tests/baselines/reference/exportClassExtendingIntersection.types new file mode 100644 index 00000000000..5840c53a056 --- /dev/null +++ b/tests/baselines/reference/exportClassExtendingIntersection.types @@ -0,0 +1,84 @@ +=== tests/cases/compiler/BaseClass.ts === +export type Constructor = new (...args: any[]) => T; +>Constructor : Constructor +>T : T +>args : any[] +>T : T + +export class MyBaseClass { +>MyBaseClass : MyBaseClass +>T : T + + baseProperty: string; +>baseProperty : string + + constructor(value: T) {} +>value : T +>T : T +} +=== tests/cases/compiler/MixinClass.ts === +import { Constructor, MyBaseClass } from './BaseClass'; +>Constructor : any +>MyBaseClass : typeof MyBaseClass + +export interface MyMixin { +>MyMixin : MyMixin + + mixinProperty: string; +>mixinProperty : string +} + +export function MyMixin>>(base: T): T & Constructor { +>MyMixin : >>(base: T) => T & Constructor +>T : T +>Constructor : Constructor +>MyBaseClass : MyBaseClass +>base : T +>T : T +>T : T +>Constructor : Constructor +>MyMixin : MyMixin + + return class extends base { +>class extends base { mixinProperty: string; } : { new (...args: any[]): (Anonymous class); prototype: MyMixin.(Anonymous class); } & T +>base : MyBaseClass + + mixinProperty: string; +>mixinProperty : string + } +} +=== tests/cases/compiler/FinalClass.ts === +import { MyBaseClass } from './BaseClass'; +>MyBaseClass : typeof MyBaseClass + +import { MyMixin } from './MixinClass'; +>MyMixin : MyBaseClass>(base: T) => T & (new (...args: any[]) => MyMixin) + +export class MyExtendedClass extends MyMixin(MyBaseClass) { +>MyExtendedClass : MyExtendedClass +>MyMixin(MyBaseClass) : MyBaseClass & MyMixin +>MyMixin : MyBaseClass>(base: T) => T & (new (...args: any[]) => MyMixin) +>MyBaseClass : typeof MyBaseClass + + extendedClassProperty: number; +>extendedClassProperty : number +} +=== tests/cases/compiler/Main.ts === +import { MyExtendedClass } from './FinalClass'; +>MyExtendedClass : typeof MyExtendedClass + +import { MyMixin } from './MixinClass'; +>MyMixin : MyBaseClass>(base: T) => T & (new (...args: any[]) => MyMixin) + +const myExtendedClass = new MyExtendedClass('string'); +>myExtendedClass : MyExtendedClass +>new MyExtendedClass('string') : MyExtendedClass +>MyExtendedClass : typeof MyExtendedClass +>'string' : "string" + +const AnotherMixedClass = MyMixin(MyExtendedClass); +>AnotherMixedClass : typeof MyExtendedClass & (new (...args: any[]) => MyMixin) +>MyMixin(MyExtendedClass) : typeof MyExtendedClass & (new (...args: any[]) => MyMixin) +>MyMixin : MyBaseClass>(base: T) => T & (new (...args: any[]) => MyMixin) +>MyExtendedClass : typeof MyExtendedClass + diff --git a/tests/baselines/reference/mixinAccessModifiers.errors.txt b/tests/baselines/reference/mixinAccessModifiers.errors.txt index a93725e01d2..fa2fc4ac99a 100644 --- a/tests/baselines/reference/mixinAccessModifiers.errors.txt +++ b/tests/baselines/reference/mixinAccessModifiers.errors.txt @@ -5,25 +5,19 @@ tests/cases/conformance/classes/mixinAccessModifiers.ts(50,4): error TS2445: Pro tests/cases/conformance/classes/mixinAccessModifiers.ts(65,7): error TS2415: Class 'C1' incorrectly extends base class 'Private & Private2'. Type 'C1' is not assignable to type 'Private'. Property 'p' has conflicting declarations and is inaccessible in type 'C1'. -tests/cases/conformance/classes/mixinAccessModifiers.ts(65,7): error TS4093: 'extends' clause of exported class 'C1' refers to a type whose name cannot be referenced. tests/cases/conformance/classes/mixinAccessModifiers.ts(66,7): error TS2415: Class 'C2' incorrectly extends base class 'Private & Protected'. Type 'C2' is not assignable to type 'Private'. Property 'p' has conflicting declarations and is inaccessible in type 'C2'. -tests/cases/conformance/classes/mixinAccessModifiers.ts(66,7): error TS4093: 'extends' clause of exported class 'C2' refers to a type whose name cannot be referenced. tests/cases/conformance/classes/mixinAccessModifiers.ts(67,7): error TS2415: Class 'C3' incorrectly extends base class 'Private & Public'. Type 'C3' is not assignable to type 'Private'. Property 'p' has conflicting declarations and is inaccessible in type 'C3'. -tests/cases/conformance/classes/mixinAccessModifiers.ts(67,7): error TS4093: 'extends' clause of exported class 'C3' refers to a type whose name cannot be referenced. -tests/cases/conformance/classes/mixinAccessModifiers.ts(69,7): error TS4093: 'extends' clause of exported class 'C4' refers to a type whose name cannot be referenced. -tests/cases/conformance/classes/mixinAccessModifiers.ts(82,7): error TS4093: 'extends' clause of exported class 'C5' refers to a type whose name cannot be referenced. tests/cases/conformance/classes/mixinAccessModifiers.ts(84,6): error TS2445: Property 'p' is protected and only accessible within class 'C4' and its subclasses. tests/cases/conformance/classes/mixinAccessModifiers.ts(89,6): error TS2445: Property 's' is protected and only accessible within class 'typeof C4' and its subclasses. -tests/cases/conformance/classes/mixinAccessModifiers.ts(95,7): error TS4093: 'extends' clause of exported class 'C6' refers to a type whose name cannot be referenced. tests/cases/conformance/classes/mixinAccessModifiers.ts(97,6): error TS2445: Property 'p' is protected and only accessible within class 'C4' and its subclasses. tests/cases/conformance/classes/mixinAccessModifiers.ts(102,6): error TS2445: Property 's' is protected and only accessible within class 'typeof C4' and its subclasses. -==== tests/cases/conformance/classes/mixinAccessModifiers.ts (17 errors) ==== +==== tests/cases/conformance/classes/mixinAccessModifiers.ts (11 errors) ==== type Constructable = new (...args: any[]) => object; class Private { @@ -101,26 +95,18 @@ tests/cases/conformance/classes/mixinAccessModifiers.ts(102,6): error TS2445: Pr !!! error TS2415: Class 'C1' incorrectly extends base class 'Private & Private2'. !!! error TS2415: Type 'C1' is not assignable to type 'Private'. !!! error TS2415: Property 'p' has conflicting declarations and is inaccessible in type 'C1'. - ~~ -!!! error TS4093: 'extends' clause of exported class 'C1' refers to a type whose name cannot be referenced. class C2 extends Mix(Private, Protected) {} ~~ !!! error TS2415: Class 'C2' incorrectly extends base class 'Private & Protected'. !!! error TS2415: Type 'C2' is not assignable to type 'Private'. !!! error TS2415: Property 'p' has conflicting declarations and is inaccessible in type 'C2'. - ~~ -!!! error TS4093: 'extends' clause of exported class 'C2' refers to a type whose name cannot be referenced. class C3 extends Mix(Private, Public) {} ~~ !!! error TS2415: Class 'C3' incorrectly extends base class 'Private & Public'. !!! error TS2415: Type 'C3' is not assignable to type 'Private'. !!! error TS2415: Property 'p' has conflicting declarations and is inaccessible in type 'C3'. - ~~ -!!! error TS4093: 'extends' clause of exported class 'C3' refers to a type whose name cannot be referenced. class C4 extends Mix(Protected, Protected2) { - ~~ -!!! error TS4093: 'extends' clause of exported class 'C4' refers to a type whose name cannot be referenced. f(c4: C4, c5: C5, c6: C6) { c4.p; c5.p; @@ -134,8 +120,6 @@ tests/cases/conformance/classes/mixinAccessModifiers.ts(102,6): error TS2445: Pr } class C5 extends Mix(Protected, Public) { - ~~ -!!! error TS4093: 'extends' clause of exported class 'C5' refers to a type whose name cannot be referenced. f(c4: C4, c5: C5, c6: C6) { c4.p; // Error, not in class deriving from Protected2 ~ @@ -153,8 +137,6 @@ tests/cases/conformance/classes/mixinAccessModifiers.ts(102,6): error TS2445: Pr } class C6 extends Mix(Public, Public2) { - ~~ -!!! error TS4093: 'extends' clause of exported class 'C6' refers to a type whose name cannot be referenced. f(c4: C4, c5: C5, c6: C6) { c4.p; // Error, not in class deriving from Protected2 ~ diff --git a/tests/baselines/reference/mixinAccessModifiers.js b/tests/baselines/reference/mixinAccessModifiers.js index 8100c9db9e9..736808455bb 100644 --- a/tests/baselines/reference/mixinAccessModifiers.js +++ b/tests/baselines/reference/mixinAccessModifiers.js @@ -263,3 +263,66 @@ var C6 = (function (_super) { }; return C6; }(Mix(Public, Public2))); + + +//// [mixinAccessModifiers.d.ts] +declare type Constructable = new (...args: any[]) => object; +declare class Private { + constructor(...args: any[]); + private p; +} +declare class Private2 { + constructor(...args: any[]); + private p; +} +declare class Protected { + constructor(...args: any[]); + protected p: string; + protected static s: string; +} +declare class Protected2 { + constructor(...args: any[]); + protected p: string; + protected static s: string; +} +declare class Public { + constructor(...args: any[]); + p: string; + static s: string; +} +declare class Public2 { + constructor(...args: any[]); + p: string; + static s: string; +} +declare function f1(x: Private & Private2): void; +declare function f2(x: Private & Protected): void; +declare function f3(x: Private & Public): void; +declare function f4(x: Protected & Protected2): void; +declare function f5(x: Protected & Public): void; +declare function f6(x: Public & Public2): void; +declare function Mix(c1: T, c2: U): T & U; +declare const C1_base: typeof Private & typeof Private2; +declare class C1 extends C1_base { +} +declare const C2_base: typeof Private & typeof Protected; +declare class C2 extends C2_base { +} +declare const C3_base: typeof Private & typeof Public; +declare class C3 extends C3_base { +} +declare const C4_base: typeof Protected & typeof Protected2; +declare class C4 extends C4_base { + f(c4: C4, c5: C5, c6: C6): void; + static g(): void; +} +declare const C5_base: typeof Protected & typeof Public; +declare class C5 extends C5_base { + f(c4: C4, c5: C5, c6: C6): void; + static g(): void; +} +declare const C6_base: typeof Public & typeof Public2; +declare class C6 extends C6_base { + f(c4: C4, c5: C5, c6: C6): void; + static g(): void; +} diff --git a/tests/baselines/reference/tsxAttributeResolution1.errors.txt b/tests/baselines/reference/tsxAttributeResolution1.errors.txt index d064f72f85d..f6c84f80fa5 100644 --- a/tests/baselines/reference/tsxAttributeResolution1.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution1.errors.txt @@ -1,15 +1,12 @@ tests/cases/conformance/jsx/file.tsx(23,8): error TS2322: Type '{ x: "0"; }' is not assignable to type 'Attribs1'. Types of property 'x' are incompatible. Type '"0"' is not assignable to type 'number'. -tests/cases/conformance/jsx/file.tsx(24,8): error TS2322: Type '{ y: 0; }' is not assignable to type 'Attribs1'. - Property 'y' does not exist on type 'Attribs1'. -tests/cases/conformance/jsx/file.tsx(25,8): error TS2322: Type '{ y: "foo"; }' is not assignable to type 'Attribs1'. - Property 'y' does not exist on type 'Attribs1'. +tests/cases/conformance/jsx/file.tsx(24,8): error TS2339: Property 'y' does not exist on type 'Attribs1'. +tests/cases/conformance/jsx/file.tsx(25,8): error TS2339: Property 'y' does not exist on type 'Attribs1'. tests/cases/conformance/jsx/file.tsx(26,8): error TS2322: Type '{ x: "32"; }' is not assignable to type 'Attribs1'. Types of property 'x' are incompatible. Type '"32"' is not assignable to type 'number'. -tests/cases/conformance/jsx/file.tsx(27,8): error TS2322: Type '{ var: "10"; }' is not assignable to type 'Attribs1'. - Property 'var' does not exist on type 'Attribs1'. +tests/cases/conformance/jsx/file.tsx(27,8): error TS2339: Property 'var' does not exist on type 'Attribs1'. tests/cases/conformance/jsx/file.tsx(29,1): error TS2322: Type '{}' is not assignable to type '{ reqd: string; }'. Property 'reqd' is missing in type '{}'. tests/cases/conformance/jsx/file.tsx(30,8): error TS2322: Type '{ reqd: 10; }' is not assignable to type '{ reqd: string; }'. @@ -47,12 +44,10 @@ tests/cases/conformance/jsx/file.tsx(30,8): error TS2322: Type '{ reqd: 10; }' i !!! error TS2322: Type '"0"' is not assignable to type 'number'. ; // Error, no property "y" ~~~~~ -!!! error TS2322: Type '{ y: 0; }' is not assignable to type 'Attribs1'. -!!! error TS2322: Property 'y' does not exist on type 'Attribs1'. +!!! error TS2339: Property 'y' does not exist on type 'Attribs1'. ; // Error, no property "y" ~~~~~~~ -!!! error TS2322: Type '{ y: "foo"; }' is not assignable to type 'Attribs1'. -!!! error TS2322: Property 'y' does not exist on type 'Attribs1'. +!!! error TS2339: Property 'y' does not exist on type 'Attribs1'. ; // Error, "32" is not number ~~~~~~ !!! error TS2322: Type '{ x: "32"; }' is not assignable to type 'Attribs1'. @@ -60,8 +55,7 @@ tests/cases/conformance/jsx/file.tsx(30,8): error TS2322: Type '{ reqd: 10; }' i !!! error TS2322: Type '"32"' is not assignable to type 'number'. ; // Error, no 'var' property ~~~~~~~~ -!!! error TS2322: Type '{ var: "10"; }' is not assignable to type 'Attribs1'. -!!! error TS2322: Property 'var' does not exist on type 'Attribs1'. +!!! error TS2339: Property 'var' does not exist on type 'Attribs1'. ; // Error, missing reqd ~~~~~~~~~ diff --git a/tests/baselines/reference/tsxAttributeResolution11.errors.txt b/tests/baselines/reference/tsxAttributeResolution11.errors.txt index 08a75c3b8bb..907b9bce776 100644 --- a/tests/baselines/reference/tsxAttributeResolution11.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution11.errors.txt @@ -1,5 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(11,22): error TS2322: Type '{ bar: "world"; }' is not assignable to type 'IntrinsicAttributes & { ref?: string; }'. - Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'. +tests/cases/conformance/jsx/file.tsx(11,22): error TS2339: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'. ==== tests/cases/conformance/jsx/react.d.ts (0 errors) ==== @@ -28,7 +27,6 @@ tests/cases/conformance/jsx/file.tsx(11,22): error TS2322: Type '{ bar: "world"; // Should be an OK var x = ; ~~~~~~~~~~~ -!!! error TS2322: Type '{ bar: "world"; }' is not assignable to type 'IntrinsicAttributes & { ref?: string; }'. -!!! error TS2322: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'. +!!! error TS2339: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution15.errors.txt b/tests/baselines/reference/tsxAttributeResolution15.errors.txt index 870599acd27..2ab79ea7aae 100644 --- a/tests/baselines/reference/tsxAttributeResolution15.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution15.errors.txt @@ -1,5 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(11,21): error TS2322: Type '{ prop1: "hello"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. - Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(11,21): error TS2339: Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. ==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== @@ -15,8 +14,7 @@ tests/cases/conformance/jsx/file.tsx(11,21): error TS2322: Type '{ prop1: "hello // Error let a = ~~~~~~~~~~~~~ -!!! error TS2322: Type '{ prop1: "hello"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. -!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. +!!! error TS2339: Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. // OK let b = { this.textInput = input; }} /> diff --git a/tests/baselines/reference/tsxAttributeResolution3.errors.txt b/tests/baselines/reference/tsxAttributeResolution3.errors.txt index d5517ea31a2..b4ec56c0c46 100644 --- a/tests/baselines/reference/tsxAttributeResolution3.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution3.errors.txt @@ -6,11 +6,9 @@ tests/cases/conformance/jsx/file.tsx(23,8): error TS2322: Type '{ y: number; }' tests/cases/conformance/jsx/file.tsx(31,8): error TS2322: Type '{ x: number; y: number; }' is not assignable to type 'Attribs1'. Types of property 'x' are incompatible. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(35,8): error TS2322: Type '{ x: string; y: number; extra: number; }' is not assignable to type 'Attribs1'. - Property 'extra' does not exist on type 'Attribs1'. -==== tests/cases/conformance/jsx/file.tsx (4 errors) ==== +==== tests/cases/conformance/jsx/file.tsx (3 errors) ==== declare module JSX { interface Element { } interface IntrinsicElements { @@ -54,12 +52,9 @@ tests/cases/conformance/jsx/file.tsx(35,8): error TS2322: Type '{ x: string; y: !!! error TS2322: Types of property 'x' are incompatible. !!! error TS2322: Type 'number' is not assignable to type 'string'. - // Error + // Ok var obj6 = { x: 'ok', y: 32, extra: 100 }; - ~~~~~~~~~ -!!! error TS2322: Type '{ x: string; y: number; extra: number; }' is not assignable to type 'Attribs1'. -!!! error TS2322: Property 'extra' does not exist on type 'Attribs1'. // OK (spread override) var obj7 = { x: 'foo' }; diff --git a/tests/baselines/reference/tsxAttributeResolution3.js b/tests/baselines/reference/tsxAttributeResolution3.js index c96fd77e284..692fb4ba0b9 100644 --- a/tests/baselines/reference/tsxAttributeResolution3.js +++ b/tests/baselines/reference/tsxAttributeResolution3.js @@ -31,7 +31,7 @@ var obj4 = { x: 32, y: 32 }; var obj5 = { x: 32, y: 32 }; -// Error +// Ok var obj6 = { x: 'ok', y: 32, extra: 100 }; @@ -56,7 +56,7 @@ var obj4 = { x: 32, y: 32 }; // Error var obj5 = { x: 32, y: 32 }; ; -// Error +// Ok var obj6 = { x: 'ok', y: 32, extra: 100 }; ; // OK (spread override) diff --git a/tests/baselines/reference/tsxElementResolution11.errors.txt b/tests/baselines/reference/tsxElementResolution11.errors.txt index f0d5cf1e009..878f5a8b337 100644 --- a/tests/baselines/reference/tsxElementResolution11.errors.txt +++ b/tests/baselines/reference/tsxElementResolution11.errors.txt @@ -1,5 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(17,7): error TS2322: Type '{ x: 10; }' is not assignable to type '{ q?: number; }'. - Property 'x' does not exist on type '{ q?: number; }'. +tests/cases/conformance/jsx/file.tsx(17,7): error TS2339: Property 'x' does not exist on type '{ q?: number; }'. ==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== @@ -21,8 +20,7 @@ tests/cases/conformance/jsx/file.tsx(17,7): error TS2322: Type '{ x: 10; }' is n var Obj2: Obj2type; ; // Error ~~~~~~ -!!! error TS2322: Type '{ x: 10; }' is not assignable to type '{ q?: number; }'. -!!! error TS2322: Property 'x' does not exist on type '{ q?: number; }'. +!!! error TS2339: Property 'x' does not exist on type '{ q?: number; }'. interface Obj3type { new(n: string): { x: number; }; diff --git a/tests/baselines/reference/tsxElementResolution3.errors.txt b/tests/baselines/reference/tsxElementResolution3.errors.txt index d869821a4cb..4e7687c94e2 100644 --- a/tests/baselines/reference/tsxElementResolution3.errors.txt +++ b/tests/baselines/reference/tsxElementResolution3.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/jsx/file.tsx(12,7): error TS2322: Type '{ w: "err"; }' is not assignable to type '{ n: string; }'. - Property 'w' does not exist on type '{ n: string; }'. + Property 'n' is missing in type '{ w: "err"; }'. ==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== @@ -17,4 +17,4 @@ tests/cases/conformance/jsx/file.tsx(12,7): error TS2322: Type '{ w: "err"; }' i ; ~~~~~~~ !!! error TS2322: Type '{ w: "err"; }' is not assignable to type '{ n: string; }'. -!!! error TS2322: Property 'w' does not exist on type '{ n: string; }'. \ No newline at end of file +!!! error TS2322: Property 'n' is missing in type '{ w: "err"; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution4.errors.txt b/tests/baselines/reference/tsxElementResolution4.errors.txt index b5d5437d872..461cfe025df 100644 --- a/tests/baselines/reference/tsxElementResolution4.errors.txt +++ b/tests/baselines/reference/tsxElementResolution4.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/jsx/file.tsx(16,7): error TS2322: Type '{ q: ""; }' is not assignable to type '{ m: string; }'. - Property 'q' does not exist on type '{ m: string; }'. + Property 'm' is missing in type '{ q: ""; }'. ==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== @@ -21,5 +21,5 @@ tests/cases/conformance/jsx/file.tsx(16,7): error TS2322: Type '{ q: ""; }' is n ; ~~~~ !!! error TS2322: Type '{ q: ""; }' is not assignable to type '{ m: string; }'. -!!! error TS2322: Property 'q' does not exist on type '{ m: string; }'. +!!! error TS2322: Property 'm' is missing in type '{ q: ""; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.errors.txt b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.errors.txt index c49bd643537..230ca1e2795 100644 --- a/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.errors.txt +++ b/tests/baselines/reference/tsxReactComponentWithDefaultTypeParameter3.errors.txt @@ -1,7 +1,5 @@ -tests/cases/conformance/jsx/file.tsx(16,17): error TS2322: Type '{ a: 10; b: "hi"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. - Property 'a' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. -tests/cases/conformance/jsx/file.tsx(17,18): error TS2322: Type '{ a: "hi"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. - Property 'a' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(16,17): error TS2339: Property 'a' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(17,18): error TS2339: Property 'a' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. ==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== @@ -21,10 +19,8 @@ tests/cases/conformance/jsx/file.tsx(17,18): error TS2322: Type '{ a: "hi"; }' i // Error let x = - ~~~~~~~~~~~~~ -!!! error TS2322: Type '{ a: 10; b: "hi"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. -!!! error TS2322: Property 'a' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. + ~~~~~~ +!!! error TS2339: Property 'a' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. let x2 = ~~~~~~ -!!! error TS2322: Type '{ a: "hi"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. -!!! error TS2322: Property 'a' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. \ No newline at end of file +!!! error TS2339: Property 'a' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & { children?: ReactNode; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution12.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution12.errors.txt index 0c1ebce61bf..a43c9270642 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution12.errors.txt +++ b/tests/baselines/reference/tsxSpreadAttributesResolution12.errors.txt @@ -6,9 +6,13 @@ tests/cases/conformance/jsx/file.tsx(28,25): error TS2322: Type '{ y: true; x: 3 Type '{ y: true; x: 3; overwrite: "hi"; }' is not assignable to type 'Prop'. Types of property 'x' are incompatible. Type '3' is not assignable to type '2'. +tests/cases/conformance/jsx/file.tsx(30,25): error TS2322: Type '{ y: true; x: 2; overwrite: "hi"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Prop & { children?: ReactNode; }'. + Type '{ y: true; x: 2; overwrite: "hi"; }' is not assignable to type 'Prop'. + Types of property 'y' are incompatible. + Type 'true' is not assignable to type 'false'. -==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== +==== tests/cases/conformance/jsx/file.tsx (3 errors) ==== import React = require('react'); const obj = {}; @@ -48,4 +52,11 @@ tests/cases/conformance/jsx/file.tsx(28,25): error TS2322: Type '{ y: true; x: 3 !!! error TS2322: Types of property 'x' are incompatible. !!! error TS2322: Type '3' is not assignable to type '2'. let x2 = + let x3 = + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ y: true; x: 2; overwrite: "hi"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Prop & { children?: ReactNode; }'. +!!! error TS2322: Type '{ y: true; x: 2; overwrite: "hi"; }' is not assignable to type 'Prop'. +!!! error TS2322: Types of property 'y' are incompatible. +!!! error TS2322: Type 'true' is not assignable to type 'false'. + \ No newline at end of file diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution12.js b/tests/baselines/reference/tsxSpreadAttributesResolution12.js index 8551a3f1bac..a68755a7592 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution12.js +++ b/tests/baselines/reference/tsxSpreadAttributesResolution12.js @@ -28,6 +28,8 @@ let anyobj: any; let x = let x1 = let x2 = +let x3 = + //// [file.jsx] @@ -67,3 +69,4 @@ var anyobj; var x = ; var x1 = ; var x2 = ; +var x3 = ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution13.js b/tests/baselines/reference/tsxSpreadAttributesResolution13.js new file mode 100644 index 00000000000..8227f3d6399 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution13.js @@ -0,0 +1,48 @@ +//// [file.tsx] +import React = require('react'); + +interface ComponentProps { + property1: string; + property2: number; +} + +export default function Component(props: ComponentProps) { + let condition1: boolean; + if (condition1) { + return ( + + ); + } + else { + return (); + } +} + +interface AnotherComponentProps { + property1: string; +} + +function ChildComponent({ property1 }: AnotherComponentProps) { + return ( + {property1} + ); +} + +//// [file.jsx] +"use strict"; +exports.__esModule = true; +var React = require("react"); +function Component(props) { + var condition1; + if (condition1) { + return (); + } + else { + return (); + } +} +exports["default"] = Component; +function ChildComponent(_a) { + var property1 = _a.property1; + return ({property1}); +} diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution13.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution13.symbols new file mode 100644 index 00000000000..2e146225792 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution13.symbols @@ -0,0 +1,60 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +interface ComponentProps { +>ComponentProps : Symbol(ComponentProps, Decl(file.tsx, 0, 32)) + + property1: string; +>property1 : Symbol(ComponentProps.property1, Decl(file.tsx, 2, 26)) + + property2: number; +>property2 : Symbol(ComponentProps.property2, Decl(file.tsx, 3, 22)) +} + +export default function Component(props: ComponentProps) { +>Component : Symbol(Component, Decl(file.tsx, 5, 1)) +>props : Symbol(props, Decl(file.tsx, 7, 34)) +>ComponentProps : Symbol(ComponentProps, Decl(file.tsx, 0, 32)) + + let condition1: boolean; +>condition1 : Symbol(condition1, Decl(file.tsx, 8, 7)) + + if (condition1) { +>condition1 : Symbol(condition1, Decl(file.tsx, 8, 7)) + + return ( + +>ChildComponent : Symbol(ChildComponent, Decl(file.tsx, 21, 1)) +>props : Symbol(props, Decl(file.tsx, 7, 34)) + + ); + } + else { + return (); +>ChildComponent : Symbol(ChildComponent, Decl(file.tsx, 21, 1)) +>props : Symbol(props, Decl(file.tsx, 7, 34)) +>property1 : Symbol(property1, Decl(file.tsx, 15, 42)) + } +} + +interface AnotherComponentProps { +>AnotherComponentProps : Symbol(AnotherComponentProps, Decl(file.tsx, 17, 1)) + + property1: string; +>property1 : Symbol(AnotherComponentProps.property1, Decl(file.tsx, 19, 33)) +} + +function ChildComponent({ property1 }: AnotherComponentProps) { +>ChildComponent : Symbol(ChildComponent, Decl(file.tsx, 21, 1)) +>property1 : Symbol(property1, Decl(file.tsx, 23, 25)) +>AnotherComponentProps : Symbol(AnotherComponentProps, Decl(file.tsx, 17, 1)) + + return ( + {property1} +>span : Symbol(JSX.IntrinsicElements.span, Decl(react.d.ts, 2460, 51)) +>property1 : Symbol(property1, Decl(file.tsx, 23, 25)) +>span : Symbol(JSX.IntrinsicElements.span, Decl(react.d.ts, 2460, 51)) + + ); +} diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution13.types b/tests/baselines/reference/tsxSpreadAttributesResolution13.types new file mode 100644 index 00000000000..5b5ada68613 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution13.types @@ -0,0 +1,68 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : typeof React + +interface ComponentProps { +>ComponentProps : ComponentProps + + property1: string; +>property1 : string + + property2: number; +>property2 : number +} + +export default function Component(props: ComponentProps) { +>Component : (props: ComponentProps) => JSX.Element +>props : ComponentProps +>ComponentProps : ComponentProps + + let condition1: boolean; +>condition1 : boolean + + if (condition1) { +>condition1 : boolean + + return ( +>( ) : JSX.Element + + +> : JSX.Element +>ChildComponent : ({property1}: AnotherComponentProps) => JSX.Element +>props : ComponentProps + + ); + } + else { + return (); +>() : JSX.Element +> : JSX.Element +>ChildComponent : ({property1}: AnotherComponentProps) => JSX.Element +>props : ComponentProps +>property1 : string + } +} + +interface AnotherComponentProps { +>AnotherComponentProps : AnotherComponentProps + + property1: string; +>property1 : string +} + +function ChildComponent({ property1 }: AnotherComponentProps) { +>ChildComponent : ({property1}: AnotherComponentProps) => JSX.Element +>property1 : string +>AnotherComponentProps : AnotherComponentProps + + return ( +>( {property1} ) : JSX.Element + + {property1} +>{property1} : JSX.Element +>span : any +>property1 : string +>span : any + + ); +} diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution14.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution14.errors.txt new file mode 100644 index 00000000000..536d2e75f84 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution14.errors.txt @@ -0,0 +1,29 @@ +tests/cases/conformance/jsx/file.tsx(11,38): error TS2339: Property 'Property1' does not exist on type 'IntrinsicAttributes & AnotherComponentProps'. + + +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== + import React = require('react'); + + interface ComponentProps { + property1: string; + property2: number; + } + + export default function Component(props: ComponentProps) { + return ( + // Error extra property + + ~~~~~~~~~ +!!! error TS2339: Property 'Property1' does not exist on type 'IntrinsicAttributes & AnotherComponentProps'. + ); + } + + interface AnotherComponentProps { + property1: string; + } + + function AnotherComponent({ property1 }: AnotherComponentProps) { + return ( + {property1} + ); + } \ No newline at end of file diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution14.js b/tests/baselines/reference/tsxSpreadAttributesResolution14.js new file mode 100644 index 00000000000..d04c9cd6d99 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution14.js @@ -0,0 +1,39 @@ +//// [file.tsx] +import React = require('react'); + +interface ComponentProps { + property1: string; + property2: number; +} + +export default function Component(props: ComponentProps) { + return ( + // Error extra property + + ); +} + +interface AnotherComponentProps { + property1: string; +} + +function AnotherComponent({ property1 }: AnotherComponentProps) { + return ( + {property1} + ); +} + +//// [file.jsx] +"use strict"; +exports.__esModule = true; +var React = require("react"); +function Component(props) { + return ( + // Error extra property + ); +} +exports["default"] = Component; +function AnotherComponent(_a) { + var property1 = _a.property1; + return ({property1}); +} diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution15.js b/tests/baselines/reference/tsxSpreadAttributesResolution15.js new file mode 100644 index 00000000000..41302f22a61 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution15.js @@ -0,0 +1,38 @@ +//// [file.tsx] +import React = require('react'); + +interface ComponentProps { + property1: string; + property2: number; +} + +export default function Component(props: ComponentProps) { + return ( + + ); +} + +interface AnotherComponentProps { + property1: string; + AnotherProperty1: string; + property2: boolean; +} + +function AnotherComponent({ property1 }: AnotherComponentProps) { + return ( + {property1} + ); +} + +//// [file.jsx] +"use strict"; +exports.__esModule = true; +var React = require("react"); +function Component(props) { + return (); +} +exports["default"] = Component; +function AnotherComponent(_a) { + var property1 = _a.property1; + return ({property1}); +} diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution15.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution15.symbols new file mode 100644 index 00000000000..00e10954821 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution15.symbols @@ -0,0 +1,55 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : Symbol(React, Decl(file.tsx, 0, 0)) + +interface ComponentProps { +>ComponentProps : Symbol(ComponentProps, Decl(file.tsx, 0, 32)) + + property1: string; +>property1 : Symbol(ComponentProps.property1, Decl(file.tsx, 2, 26)) + + property2: number; +>property2 : Symbol(ComponentProps.property2, Decl(file.tsx, 3, 22)) +} + +export default function Component(props: ComponentProps) { +>Component : Symbol(Component, Decl(file.tsx, 5, 1)) +>props : Symbol(props, Decl(file.tsx, 7, 34)) +>ComponentProps : Symbol(ComponentProps, Decl(file.tsx, 0, 32)) + + return ( + +>AnotherComponent : Symbol(AnotherComponent, Decl(file.tsx, 17, 1)) +>props : Symbol(props, Decl(file.tsx, 7, 34)) +>property2 : Symbol(property2, Decl(file.tsx, 9, 36)) +>AnotherProperty1 : Symbol(AnotherProperty1, Decl(file.tsx, 9, 46)) + + ); +} + +interface AnotherComponentProps { +>AnotherComponentProps : Symbol(AnotherComponentProps, Decl(file.tsx, 11, 1)) + + property1: string; +>property1 : Symbol(AnotherComponentProps.property1, Decl(file.tsx, 13, 33)) + + AnotherProperty1: string; +>AnotherProperty1 : Symbol(AnotherComponentProps.AnotherProperty1, Decl(file.tsx, 14, 22)) + + property2: boolean; +>property2 : Symbol(AnotherComponentProps.property2, Decl(file.tsx, 15, 29)) +} + +function AnotherComponent({ property1 }: AnotherComponentProps) { +>AnotherComponent : Symbol(AnotherComponent, Decl(file.tsx, 17, 1)) +>property1 : Symbol(property1, Decl(file.tsx, 19, 27)) +>AnotherComponentProps : Symbol(AnotherComponentProps, Decl(file.tsx, 11, 1)) + + return ( + {property1} +>span : Symbol(JSX.IntrinsicElements.span, Decl(react.d.ts, 2460, 51)) +>property1 : Symbol(property1, Decl(file.tsx, 19, 27)) +>span : Symbol(JSX.IntrinsicElements.span, Decl(react.d.ts, 2460, 51)) + + ); +} diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution15.types b/tests/baselines/reference/tsxSpreadAttributesResolution15.types new file mode 100644 index 00000000000..dbcb6541a03 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution15.types @@ -0,0 +1,61 @@ +=== tests/cases/conformance/jsx/file.tsx === +import React = require('react'); +>React : typeof React + +interface ComponentProps { +>ComponentProps : ComponentProps + + property1: string; +>property1 : string + + property2: number; +>property2 : number +} + +export default function Component(props: ComponentProps) { +>Component : (props: ComponentProps) => JSX.Element +>props : ComponentProps +>ComponentProps : ComponentProps + + return ( +>( ) : JSX.Element + + +> : JSX.Element +>AnotherComponent : ({property1}: AnotherComponentProps) => JSX.Element +>props : ComponentProps +>property2 : true +>AnotherProperty1 : string + + ); +} + +interface AnotherComponentProps { +>AnotherComponentProps : AnotherComponentProps + + property1: string; +>property1 : string + + AnotherProperty1: string; +>AnotherProperty1 : string + + property2: boolean; +>property2 : boolean +} + +function AnotherComponent({ property1 }: AnotherComponentProps) { +>AnotherComponent : ({property1}: AnotherComponentProps) => JSX.Element +>property1 : string +>AnotherComponentProps : AnotherComponentProps + + return ( +>( {property1} ) : JSX.Element + + {property1} +>{property1} : JSX.Element +>span : any +>property1 : string +>span : any + + ); +} diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution16.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution16.errors.txt new file mode 100644 index 00000000000..ddfb9c1c6cf --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution16.errors.txt @@ -0,0 +1,35 @@ +tests/cases/conformance/jsx/file.tsx(11,27): error TS2322: Type '{ property1: string; property2: number; }' is not assignable to type 'IntrinsicAttributes & AnotherComponentProps'. + Type '{ property1: string; property2: number; }' is not assignable to type 'AnotherComponentProps'. + Property 'AnotherProperty1' is missing in type '{ property1: string; property2: number; }'. + + +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== + import React = require('react'); + + interface ComponentProps { + property1: string; + property2: number; + } + + export default function Component(props: ComponentProps) { + return ( + // Error: missing property + + ~~~~~~~~~~ +!!! error TS2322: Type '{ property1: string; property2: number; }' is not assignable to type 'IntrinsicAttributes & AnotherComponentProps'. +!!! error TS2322: Type '{ property1: string; property2: number; }' is not assignable to type 'AnotherComponentProps'. +!!! error TS2322: Property 'AnotherProperty1' is missing in type '{ property1: string; property2: number; }'. + ); + } + + interface AnotherComponentProps { + property1: string; + AnotherProperty1: string; + property2: boolean; + } + + function AnotherComponent({ property1 }: AnotherComponentProps) { + return ( + {property1} + ); + } \ No newline at end of file diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution16.js b/tests/baselines/reference/tsxSpreadAttributesResolution16.js new file mode 100644 index 00000000000..ad0d4b01885 --- /dev/null +++ b/tests/baselines/reference/tsxSpreadAttributesResolution16.js @@ -0,0 +1,41 @@ +//// [file.tsx] +import React = require('react'); + +interface ComponentProps { + property1: string; + property2: number; +} + +export default function Component(props: ComponentProps) { + return ( + // Error: missing property + + ); +} + +interface AnotherComponentProps { + property1: string; + AnotherProperty1: string; + property2: boolean; +} + +function AnotherComponent({ property1 }: AnotherComponentProps) { + return ( + {property1} + ); +} + +//// [file.jsx] +"use strict"; +exports.__esModule = true; +var React = require("react"); +function Component(props) { + return ( + // Error: missing property + ); +} +exports["default"] = Component; +function AnotherComponent(_a) { + var property1 = _a.property1; + return ({property1}); +} diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt index 57b616124d1..06a0c4bbea6 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt +++ b/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt @@ -8,9 +8,17 @@ tests/cases/conformance/jsx/file.tsx(19,19): error TS2322: Type '{ x: true; y: t Type '{ x: true; y: true; }' is not assignable to type 'PoisonedProp'. Types of property 'x' are incompatible. Type 'true' is not assignable to type 'string'. +tests/cases/conformance/jsx/file.tsx(20,19): error TS2322: Type '{ x: number; y: "2"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. + Type '{ x: number; y: "2"; }' is not assignable to type 'PoisonedProp'. + Types of property 'x' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/jsx/file.tsx(21,20): error TS2322: Type '{ X: "hi"; x: number; y: "2"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. + Type '{ X: "hi"; x: number; y: "2"; }' is not assignable to type 'PoisonedProp'. + Types of property 'x' are incompatible. + Type 'number' is not assignable to type 'string'. -==== tests/cases/conformance/jsx/file.tsx (3 errors) ==== +==== tests/cases/conformance/jsx/file.tsx (5 errors) ==== import React = require('react'); interface PoisonedProp { @@ -42,4 +50,16 @@ tests/cases/conformance/jsx/file.tsx(19,19): error TS2322: Type '{ x: true; y: t !!! error TS2322: Type '{ x: true; y: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. !!! error TS2322: Type '{ x: true; y: true; }' is not assignable to type 'PoisonedProp'. !!! error TS2322: Types of property 'x' are incompatible. -!!! error TS2322: Type 'true' is not assignable to type 'string'. \ No newline at end of file +!!! error TS2322: Type 'true' is not assignable to type 'string'. + let w = ; + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ x: number; y: "2"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. +!!! error TS2322: Type '{ x: number; y: "2"; }' is not assignable to type 'PoisonedProp'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + let w1 = ; + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ X: "hi"; x: number; y: "2"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. +!!! error TS2322: Type '{ X: "hi"; x: number; y: "2"; }' is not assignable to type 'PoisonedProp'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution2.js b/tests/baselines/reference/tsxSpreadAttributesResolution2.js index 75da8fc2291..ad2af275485 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution2.js +++ b/tests/baselines/reference/tsxSpreadAttributesResolution2.js @@ -17,7 +17,9 @@ const obj = {}; // Error let p = ; let y = ; -let z = ; +let z = ; +let w = ; +let w1 = ; //// [file.jsx] "use strict"; @@ -48,3 +50,5 @@ var obj = {}; var p = ; var y = ; var z = ; +var w = ; +var w1 = ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution5.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution5.errors.txt index 2212d0da025..be7018512f9 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution5.errors.txt +++ b/tests/baselines/reference/tsxSpreadAttributesResolution5.errors.txt @@ -2,11 +2,9 @@ tests/cases/conformance/jsx/file.tsx(20,19): error TS2322: Type '{ x: string; y: Type '{ x: string; y: number; }' is not assignable to type 'PoisonedProp'. Types of property 'y' are incompatible. Type 'number' is not assignable to type '2'. -tests/cases/conformance/jsx/file.tsx(33,20): error TS2322: Type '{ prop1: boolean; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. - Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. -==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== import React = require('react'); interface PoisonedProp { @@ -43,8 +41,5 @@ tests/cases/conformance/jsx/file.tsx(33,20): error TS2322: Type '{ prop1: boolea let o = { prop1: false } - // Error - let e = ; - ~~~~~~ -!!! error TS2322: Type '{ prop1: boolean; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. -!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. \ No newline at end of file + // Ok + let e = ; \ No newline at end of file diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution5.js b/tests/baselines/reference/tsxSpreadAttributesResolution5.js index a40139b316e..192f4b78770 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution5.js +++ b/tests/baselines/reference/tsxSpreadAttributesResolution5.js @@ -30,7 +30,7 @@ class EmptyProp extends React.Component<{}, {}> { let o = { prop1: false } -// Error +// Ok let e = ; //// [file.jsx] @@ -76,5 +76,5 @@ var EmptyProp = (function (_super) { var o = { prop1: false }; -// Error +// Ok var e = ; diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt index b59b1dd44f4..4f717bfca96 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt @@ -1,5 +1,6 @@ tests/cases/conformance/jsx/file.tsx(12,22): error TS2322: Type '{ extraProp: true; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. - Property 'extraProp' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. + Type '{ extraProp: true; }' is not assignable to type '{ yy: number; yy1: string; }'. + Property 'yy' is missing in type '{ extraProp: true; }'. tests/cases/conformance/jsx/file.tsx(13,22): error TS2322: Type '{ yy: 10; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. Type '{ yy: 10; }' is not assignable to type '{ yy: number; yy1: string; }'. Property 'yy1' is missing in type '{ yy: 10; }'. @@ -7,10 +8,7 @@ tests/cases/conformance/jsx/file.tsx(14,22): error TS2322: Type '{ yy1: true; yy Type '{ yy1: true; yy: number; }' is not assignable to type '{ yy: number; yy1: string; }'. Types of property 'yy1' are incompatible. Type 'true' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(15,22): error TS2322: Type '{ extra: string; yy: number; yy1: string; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. - Property 'extra' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. -tests/cases/conformance/jsx/file.tsx(16,22): error TS2322: Type '{ y1: 10000; yy: number; yy1: string; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. - Property 'y1' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. +tests/cases/conformance/jsx/file.tsx(16,31): error TS2339: Property 'y1' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. tests/cases/conformance/jsx/file.tsx(17,22): error TS2322: Type '{ yy: boolean; yy1: string; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. Type '{ yy: boolean; yy1: string; }' is not assignable to type '{ yy: number; yy1: string; }'. Types of property 'yy' are incompatible. @@ -31,12 +29,16 @@ tests/cases/conformance/jsx/file.tsx(34,29): error TS2322: Type '{ y1: "hello"; Types of property 'y1' are incompatible. Type '"hello"' is not assignable to type 'boolean'. tests/cases/conformance/jsx/file.tsx(35,29): error TS2322: Type '{ y1: "hello"; y2: 1000; children: "hi"; }' is not assignable to type 'IntrinsicAttributes & { y1: boolean; y2?: number; y3: boolean; }'. - Property 'children' does not exist on type 'IntrinsicAttributes & { y1: boolean; y2?: number; y3: boolean; }'. + Type '{ y1: "hello"; y2: 1000; children: "hi"; }' is not assignable to type '{ y1: boolean; y2?: number; y3: boolean; }'. + Types of property 'y1' are incompatible. + Type '"hello"' is not assignable to type 'boolean'. tests/cases/conformance/jsx/file.tsx(36,29): error TS2322: Type '{ y1: "hello"; y2: 1000; children: string; }' is not assignable to type 'IntrinsicAttributes & { y1: boolean; y2?: number; y3: boolean; }'. - Property 'children' does not exist on type 'IntrinsicAttributes & { y1: boolean; y2?: number; y3: boolean; }'. + Type '{ y1: "hello"; y2: 1000; children: string; }' is not assignable to type '{ y1: boolean; y2?: number; y3: boolean; }'. + Types of property 'y1' are incompatible. + Type '"hello"' is not assignable to type 'boolean'. -==== tests/cases/conformance/jsx/file.tsx (12 errors) ==== +==== tests/cases/conformance/jsx/file.tsx (11 errors) ==== import React = require('react') declare function OneThing(): JSX.Element; declare function OneThing(l: {yy: number, yy1: string}): JSX.Element; @@ -51,7 +53,8 @@ tests/cases/conformance/jsx/file.tsx(36,29): error TS2322: Type '{ y1: "hello"; const c0 = ; // extra property; ~~~~~~~~~ !!! error TS2322: Type '{ extraProp: true; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. -!!! error TS2322: Property 'extraProp' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. +!!! error TS2322: Type '{ extraProp: true; }' is not assignable to type '{ yy: number; yy1: string; }'. +!!! error TS2322: Property 'yy' is missing in type '{ extraProp: true; }'. const c1 = ; // missing property; ~~~~~~~ !!! error TS2322: Type '{ yy: 10; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. @@ -63,14 +66,10 @@ tests/cases/conformance/jsx/file.tsx(36,29): error TS2322: Type '{ y1: "hello"; !!! error TS2322: Type '{ yy1: true; yy: number; }' is not assignable to type '{ yy: number; yy1: string; }'. !!! error TS2322: Types of property 'yy1' are incompatible. !!! error TS2322: Type 'true' is not assignable to type 'string'. - const c3 = ; // Extra attribute; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ extra: string; yy: number; yy1: string; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. -!!! error TS2322: Property 'extra' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. + const c3 = ; // This is OK becuase all attribute are spread const c4 = ; // extra property; - ~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ y1: 10000; yy: number; yy1: string; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. -!!! error TS2322: Property 'y1' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. + ~~~~~~~~~~ +!!! error TS2339: Property 'y1' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. const c5 = ; // type incompatible; ~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ yy: boolean; yy1: string; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. @@ -116,9 +115,13 @@ tests/cases/conformance/jsx/file.tsx(36,29): error TS2322: Type '{ y1: "hello"; const e3 = ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ y1: "hello"; y2: 1000; children: "hi"; }' is not assignable to type 'IntrinsicAttributes & { y1: boolean; y2?: number; y3: boolean; }'. -!!! error TS2322: Property 'children' does not exist on type 'IntrinsicAttributes & { y1: boolean; y2?: number; y3: boolean; }'. +!!! error TS2322: Type '{ y1: "hello"; y2: 1000; children: "hi"; }' is not assignable to type '{ y1: boolean; y2?: number; y3: boolean; }'. +!!! error TS2322: Types of property 'y1' are incompatible. +!!! error TS2322: Type '"hello"' is not assignable to type 'boolean'. const e4 = Hi ~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ y1: "hello"; y2: 1000; children: string; }' is not assignable to type 'IntrinsicAttributes & { y1: boolean; y2?: number; y3: boolean; }'. -!!! error TS2322: Property 'children' does not exist on type 'IntrinsicAttributes & { y1: boolean; y2?: number; y3: boolean; }'. +!!! error TS2322: Type '{ y1: "hello"; y2: 1000; children: string; }' is not assignable to type '{ y1: boolean; y2?: number; y3: boolean; }'. +!!! error TS2322: Types of property 'y1' are incompatible. +!!! error TS2322: Type '"hello"' is not assignable to type 'boolean'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.js b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.js index 8da2bee37ea..d67466d1271 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.js +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.js @@ -13,7 +13,7 @@ let obj2: any; const c0 = ; // extra property; const c1 = ; // missing property; const c2 = ; // type incompatible; -const c3 = ; // Extra attribute; +const c3 = ; // This is OK becuase all attribute are spread const c4 = ; // extra property; const c5 = ; // type incompatible; const c6 = ; // Should error as there is extra attribute that doesn't match any. Current it is not @@ -50,7 +50,7 @@ define(["require", "exports", "react"], function (require, exports, React) { var c0 = ; // extra property; var c1 = ; // missing property; var c2 = ; // type incompatible; - var c3 = ; // Extra attribute; + var c3 = ; // This is OK becuase all attribute are spread var c4 = ; // extra property; var c5 = ; // type incompatible; var c6 = ; // Should error as there is extra attribute that doesn't match any. Current it is not diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt index a7b787c1c18..b7e4fc78e0e 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt @@ -1,17 +1,24 @@ tests/cases/conformance/jsx/file.tsx(48,24): error TS2322: Type '{ to: "/some/path"; onClick: (e: MouseEvent) => void; children: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. - Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. + Type '{ to: "/some/path"; onClick: (e: MouseEvent) => void; children: string; }' is not assignable to type 'HyphenProps'. + Property '"data-format"' is missing in type '{ to: "/some/path"; onClick: (e: MouseEvent) => void; children: string; }'. tests/cases/conformance/jsx/file.tsx(49,24): error TS2322: Type '{ to: string; onClick: (e: any) => void; children: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. - Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. + Type '{ to: string; onClick: (e: any) => void; children: string; }' is not assignable to type 'HyphenProps'. + Property '"data-format"' is missing in type '{ to: string; onClick: (e: any) => void; children: string; }'. tests/cases/conformance/jsx/file.tsx(50,24): error TS2322: Type '{ onClick: () => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. - Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. + Type '{ onClick: () => void; to: string; }' is not assignable to type 'HyphenProps'. + Property '"data-format"' is missing in type '{ onClick: () => void; to: string; }'. tests/cases/conformance/jsx/file.tsx(51,24): error TS2322: Type '{ onClick: (k: MouseEvent) => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. - Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. + Type '{ onClick: (k: MouseEvent) => void; to: string; }' is not assignable to type 'HyphenProps'. + Property '"data-format"' is missing in type '{ onClick: (k: MouseEvent) => void; to: string; }'. tests/cases/conformance/jsx/file.tsx(53,24): error TS2322: Type '{ to: string; onClick(e: any): void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. - Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. + Type '{ to: string; onClick(e: any): void; }' is not assignable to type 'HyphenProps'. + Property '"data-format"' is missing in type '{ to: string; onClick(e: any): void; }'. tests/cases/conformance/jsx/file.tsx(54,24): error TS2322: Type '{ children: 10; onClick(e: any): void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. - Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. + Type '{ children: 10; onClick(e: any): void; }' is not assignable to type 'HyphenProps'. + Property '"data-format"' is missing in type '{ children: 10; onClick(e: any): void; }'. tests/cases/conformance/jsx/file.tsx(55,24): error TS2322: Type '{ children: "hello"; className: true; onClick(e: any): void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. - Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. + Type '{ children: "hello"; className: true; onClick(e: any): void; }' is not assignable to type 'HyphenProps'. + Property '"data-format"' is missing in type '{ children: "hello"; className: true; onClick(e: any): void; }'. tests/cases/conformance/jsx/file.tsx(56,24): error TS2322: Type '{ data-format: true; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. Type '{ data-format: true; }' is not assignable to type 'HyphenProps'. Types of property '"data-format"' are incompatible. @@ -69,32 +76,39 @@ tests/cases/conformance/jsx/file.tsx(56,24): error TS2322: Type '{ data-format: const b0 = {}}>GO; // extra property; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ to: "/some/path"; onClick: (e: MouseEvent) => void; children: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. -!!! error TS2322: Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Type '{ to: "/some/path"; onClick: (e: MouseEvent) => void; children: string; }' is not assignable to type 'HyphenProps'. +!!! error TS2322: Property '"data-format"' is missing in type '{ to: "/some/path"; onClick: (e: MouseEvent) => void; children: string; }'. const b1 = {}} {...obj0}>Hello world; // extra property; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ to: string; onClick: (e: any) => void; children: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. -!!! error TS2322: Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Type '{ to: string; onClick: (e: any) => void; children: string; }' is not assignable to type 'HyphenProps'. +!!! error TS2322: Property '"data-format"' is missing in type '{ to: string; onClick: (e: any) => void; children: string; }'. const b2 = ; // extra property ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ onClick: () => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. -!!! error TS2322: Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Type '{ onClick: () => void; to: string; }' is not assignable to type 'HyphenProps'. +!!! error TS2322: Property '"data-format"' is missing in type '{ onClick: () => void; to: string; }'. const b3 = {}}} />; // extra property ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ onClick: (k: MouseEvent) => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. -!!! error TS2322: Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Type '{ onClick: (k: MouseEvent) => void; to: string; }' is not assignable to type 'HyphenProps'. +!!! error TS2322: Property '"data-format"' is missing in type '{ onClick: (k: MouseEvent) => void; to: string; }'. const b4 = ; // Should error because Incorrect type; but attributes are any so everything is allowed const b5 = ; // Spread retain method declaration (see GitHub #13365), so now there is an extra attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ to: string; onClick(e: any): void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. -!!! error TS2322: Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Type '{ to: string; onClick(e: any): void; }' is not assignable to type 'HyphenProps'. +!!! error TS2322: Property '"data-format"' is missing in type '{ to: string; onClick(e: any): void; }'. const b6 = ; // incorrect type for optional attribute ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ children: 10; onClick(e: any): void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. -!!! error TS2322: Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Type '{ children: 10; onClick(e: any): void; }' is not assignable to type 'HyphenProps'. +!!! error TS2322: Property '"data-format"' is missing in type '{ children: 10; onClick(e: any): void; }'. const b7 = ; // incorrect type for optional attribute ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ children: "hello"; className: true; onClick(e: any): void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. -!!! error TS2322: Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2322: Type '{ children: "hello"; className: true; onClick(e: any): void; }' is not assignable to type 'HyphenProps'. +!!! error TS2322: Property '"data-format"' is missing in type '{ children: "hello"; className: true; onClick(e: any): void; }'. const b8 = ; // incorrect type for specified hyphanated name ~~~~~~~~~~~ !!! error TS2322: Type '{ data-format: true; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt index 51e1de2a57e..243f29493bf 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt @@ -1,24 +1,20 @@ tests/cases/conformance/jsx/file.tsx(19,16): error TS2322: Type '{ naaame: "world"; }' is not assignable to type 'IntrinsicAttributes & { name: string; }'. - Property 'naaame' does not exist on type 'IntrinsicAttributes & { name: string; }'. + Type '{ naaame: "world"; }' is not assignable to type '{ name: string; }'. + Property 'name' is missing in type '{ naaame: "world"; }'. tests/cases/conformance/jsx/file.tsx(27,15): error TS2322: Type '{ name: 42; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. Type '{ name: 42; }' is not assignable to type '{ name?: string; }'. Types of property 'name' are incompatible. Type '42' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(29,15): error TS2322: Type '{ naaaaaaame: "no"; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. - Property 'naaaaaaame' does not exist on type 'IntrinsicAttributes & { name?: string; }'. +tests/cases/conformance/jsx/file.tsx(29,15): error TS2339: Property 'naaaaaaame' does not exist on type 'IntrinsicAttributes & { name?: string; }'. tests/cases/conformance/jsx/file.tsx(34,23): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { "prop-name": string; }'. Type '{}' is not assignable to type '{ "prop-name": string; }'. Property '"prop-name"' is missing in type '{}'. -tests/cases/conformance/jsx/file.tsx(37,23): error TS2322: Type '{ prop1: true; }' is not assignable to type 'IntrinsicAttributes'. - Property 'prop1' does not exist on type 'IntrinsicAttributes'. -tests/cases/conformance/jsx/file.tsx(38,24): error TS2322: Type '{ ref: (x: any) => any; }' is not assignable to type 'IntrinsicAttributes'. - Property 'ref' does not exist on type 'IntrinsicAttributes'. +tests/cases/conformance/jsx/file.tsx(37,23): error TS2339: Property 'prop1' does not exist on type 'IntrinsicAttributes'. +tests/cases/conformance/jsx/file.tsx(38,24): error TS2339: Property 'ref' does not exist on type 'IntrinsicAttributes'. tests/cases/conformance/jsx/file.tsx(41,16): error TS1005: ',' expected. -tests/cases/conformance/jsx/file.tsx(45,24): error TS2322: Type '{ prop1: boolean; }' is not assignable to type 'IntrinsicAttributes'. - Property 'prop1' does not exist on type 'IntrinsicAttributes'. -==== tests/cases/conformance/jsx/file.tsx (8 errors) ==== +==== tests/cases/conformance/jsx/file.tsx (7 errors) ==== function EmptyPropSFC() { return
Default Greeting
; } @@ -40,7 +36,8 @@ tests/cases/conformance/jsx/file.tsx(45,24): error TS2322: Type '{ prop1: boolea let b = ; ~~~~~~~~~~~~~~ !!! error TS2322: Type '{ naaame: "world"; }' is not assignable to type 'IntrinsicAttributes & { name: string; }'. -!!! error TS2322: Property 'naaame' does not exist on type 'IntrinsicAttributes & { name: string; }'. +!!! error TS2322: Type '{ naaame: "world"; }' is not assignable to type '{ name: string; }'. +!!! error TS2322: Property 'name' is missing in type '{ naaame: "world"; }'. // OK let c = ; @@ -57,8 +54,7 @@ tests/cases/conformance/jsx/file.tsx(45,24): error TS2322: Type '{ prop1: boolea // Error let f = ; ~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ naaaaaaame: "no"; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. -!!! error TS2322: Property 'naaaaaaame' does not exist on type 'IntrinsicAttributes & { name?: string; }'. +!!! error TS2339: Property 'naaaaaaame' does not exist on type 'IntrinsicAttributes & { name?: string; }'. // OK let g = ; @@ -72,12 +68,10 @@ tests/cases/conformance/jsx/file.tsx(45,24): error TS2322: Type '{ prop1: boolea // Error let i = ~~~~~ -!!! error TS2322: Type '{ prop1: true; }' is not assignable to type 'IntrinsicAttributes'. -!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes'. +!!! error TS2339: Property 'prop1' does not exist on type 'IntrinsicAttributes'. let i1 = x.greeting.substr(10)} /> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ ref: (x: any) => any; }' is not assignable to type 'IntrinsicAttributes'. -!!! error TS2322: Property 'ref' does not exist on type 'IntrinsicAttributes'. +!!! error TS2339: Property 'ref' does not exist on type 'IntrinsicAttributes'. let o = { prop1: true; @@ -85,11 +79,8 @@ tests/cases/conformance/jsx/file.tsx(45,24): error TS2322: Type '{ prop1: boolea !!! error TS1005: ',' expected. } - // Error + // OK as access properties are allow when spread let i2 = - ~~~~~~ -!!! error TS2322: Type '{ prop1: boolean; }' is not assignable to type 'IntrinsicAttributes'. -!!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes'. let o1: any; // OK diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents1.js b/tests/baselines/reference/tsxStatelessFunctionComponents1.js index d19f1ce1073..6ede59b4420 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents1.js +++ b/tests/baselines/reference/tsxStatelessFunctionComponents1.js @@ -42,7 +42,7 @@ let o = { prop1: true; } -// Error +// OK as access properties are allow when spread let i2 = let o1: any; @@ -93,7 +93,7 @@ var i1 = ; var o = { prop1: true }; -// Error +// OK as access properties are allow when spread var i2 = ; var o1; // OK diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt index 275017ecd82..00e2c4a526c 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt @@ -1,5 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(19,16): error TS2322: Type '{ ref: "myRef"; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. - Property 'ref' does not exist on type 'IntrinsicAttributes & { name?: string; }'. +tests/cases/conformance/jsx/file.tsx(19,16): error TS2339: Property 'ref' does not exist on type 'IntrinsicAttributes & { name?: string; }'. tests/cases/conformance/jsx/file.tsx(25,42): error TS2339: Property 'subtr' does not exist on type 'string'. tests/cases/conformance/jsx/file.tsx(27,33): error TS2339: Property 'notARealProperty' does not exist on type 'BigGreeter'. tests/cases/conformance/jsx/file.tsx(35,26): error TS2339: Property 'propertyNotOnHtmlDivElement' does not exist on type 'HTMLDivElement'. @@ -26,8 +25,7 @@ tests/cases/conformance/jsx/file.tsx(35,26): error TS2339: Property 'propertyNot // Error - not allowed to specify 'ref' on SFCs let c = ; ~~~~~~~~~~~ -!!! error TS2322: Type '{ ref: "myRef"; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. -!!! error TS2322: Property 'ref' does not exist on type 'IntrinsicAttributes & { name?: string; }'. +!!! error TS2339: Property 'ref' does not exist on type 'IntrinsicAttributes & { name?: string; }'. // OK - ref is valid for classes diff --git a/tests/baselines/reference/tsxUnionElementType4.errors.txt b/tests/baselines/reference/tsxUnionElementType4.errors.txt index 7c94a08b6ef..4658b566cc7 100644 --- a/tests/baselines/reference/tsxUnionElementType4.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType4.errors.txt @@ -3,10 +3,8 @@ tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type '{ x: true; }' i Type '{ x: true; }' is not assignable to type '{ x: string; }'. Types of property 'x' are incompatible. Type 'true' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(33,21): error TS2322: Type '{ x: 10; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. - Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. -tests/cases/conformance/jsx/file.tsx(34,22): error TS2322: Type '{ prop: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. - Property 'prop' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(33,21): error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(34,22): error TS2339: Property 'prop' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. ==== tests/cases/conformance/jsx/file.tsx (3 errors) ==== @@ -50,10 +48,8 @@ tests/cases/conformance/jsx/file.tsx(34,22): error TS2322: Type '{ prop: true; } !!! error TS2322: Type 'true' is not assignable to type 'string'. let b = ~~~~~~ -!!! error TS2322: Type '{ x: 10; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. -!!! error TS2322: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. +!!! error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. let c = ; ~~~~ -!!! error TS2322: Type '{ prop: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. -!!! error TS2322: Property 'prop' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. +!!! error TS2339: Property 'prop' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxUnionElementType6.errors.txt b/tests/baselines/reference/tsxUnionElementType6.errors.txt index 1f31fb21f26..cac96565b80 100644 --- a/tests/baselines/reference/tsxUnionElementType6.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType6.errors.txt @@ -1,5 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(18,23): error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes'. - Property 'x' does not exist on type 'IntrinsicAttributes'. +tests/cases/conformance/jsx/file.tsx(18,23): error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes'. tests/cases/conformance/jsx/file.tsx(19,27): error TS2322: Type '{ x: "hi"; }' is not assignable to type 'IntrinsicAttributes & { x: boolean; }'. Type '{ x: "hi"; }' is not assignable to type '{ x: boolean; }'. Types of property 'x' are incompatible. @@ -32,8 +31,7 @@ tests/cases/conformance/jsx/file.tsx(21,27): error TS2322: Type '{}' is not assi // Error let a = ; ~ -!!! error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes'. -!!! error TS2322: Property 'x' does not exist on type 'IntrinsicAttributes'. +!!! error TS2339: Property 'x' does not exist on type 'IntrinsicAttributes'. let b = ; ~~~~~~ !!! error TS2322: Type '{ x: "hi"; }' is not assignable to type 'IntrinsicAttributes & { x: boolean; }'. diff --git a/tests/baselines/reference/typeVariableTypeGuards.js b/tests/baselines/reference/typeVariableTypeGuards.js new file mode 100644 index 00000000000..8525bde0f77 --- /dev/null +++ b/tests/baselines/reference/typeVariableTypeGuards.js @@ -0,0 +1,158 @@ +//// [typeVariableTypeGuards.ts] +// Repro from #14091 + +interface Foo { + foo(): void +} + +class A

> { + props: Readonly

+ doSomething() { + this.props.foo && this.props.foo() + } +} + +// Repro from #14415 + +interface Banana { + color: 'yellow'; +} + +class Monkey { + a: T; + render() { + if (this.a) { + this.a.color; + } + } +} + +interface BigBanana extends Banana { +} + +class BigMonkey extends Monkey { + render() { + if (this.a) { + this.a.color; + } + } +} + +// Another repro + +type Item = { + (): string; + x: string; +} + +function f1(obj: T) { + if (obj) { + obj.x; + obj["x"]; + obj(); + } +} + +function f2(obj: T | undefined) { + if (obj) { + obj.x; + obj["x"]; + obj(); + } +} + +function f3(obj: T | null) { + if (obj) { + obj.x; + obj["x"]; + obj(); + } +} + +function f4(obj: T | undefined, x: number) { + if (obj) { + obj[x].length; + } +} + +function f5(obj: T | undefined, key: K) { + if (obj) { + obj[key]; + } +} + + +//// [typeVariableTypeGuards.js] +"use strict"; +// Repro from #14091 +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var A = (function () { + function A() { + } + A.prototype.doSomething = function () { + this.props.foo && this.props.foo(); + }; + return A; +}()); +var Monkey = (function () { + function Monkey() { + } + Monkey.prototype.render = function () { + if (this.a) { + this.a.color; + } + }; + return Monkey; +}()); +var BigMonkey = (function (_super) { + __extends(BigMonkey, _super); + function BigMonkey() { + return _super !== null && _super.apply(this, arguments) || this; + } + BigMonkey.prototype.render = function () { + if (this.a) { + this.a.color; + } + }; + return BigMonkey; +}(Monkey)); +function f1(obj) { + if (obj) { + obj.x; + obj["x"]; + obj(); + } +} +function f2(obj) { + if (obj) { + obj.x; + obj["x"]; + obj(); + } +} +function f3(obj) { + if (obj) { + obj.x; + obj["x"]; + obj(); + } +} +function f4(obj, x) { + if (obj) { + obj[x].length; + } +} +function f5(obj, key) { + if (obj) { + obj[key]; + } +} diff --git a/tests/baselines/reference/typeVariableTypeGuards.symbols b/tests/baselines/reference/typeVariableTypeGuards.symbols new file mode 100644 index 00000000000..fa94cfd9462 --- /dev/null +++ b/tests/baselines/reference/typeVariableTypeGuards.symbols @@ -0,0 +1,221 @@ +=== tests/cases/compiler/typeVariableTypeGuards.ts === +// Repro from #14091 + +interface Foo { +>Foo : Symbol(Foo, Decl(typeVariableTypeGuards.ts, 0, 0)) + + foo(): void +>foo : Symbol(Foo.foo, Decl(typeVariableTypeGuards.ts, 2, 15)) +} + +class A

> { +>A : Symbol(A, Decl(typeVariableTypeGuards.ts, 4, 1)) +>P : Symbol(P, Decl(typeVariableTypeGuards.ts, 6, 8)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Foo : Symbol(Foo, Decl(typeVariableTypeGuards.ts, 0, 0)) + + props: Readonly

+>props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>P : Symbol(P, Decl(typeVariableTypeGuards.ts, 6, 8)) + + doSomething() { +>doSomething : Symbol(A.doSomething, Decl(typeVariableTypeGuards.ts, 7, 22)) + + this.props.foo && this.props.foo() +>this.props.foo : Symbol(foo) +>this.props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33)) +>this : Symbol(A, Decl(typeVariableTypeGuards.ts, 4, 1)) +>props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33)) +>foo : Symbol(foo) +>this.props.foo : Symbol(foo) +>this.props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33)) +>this : Symbol(A, Decl(typeVariableTypeGuards.ts, 4, 1)) +>props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33)) +>foo : Symbol(foo) + } +} + +// Repro from #14415 + +interface Banana { +>Banana : Symbol(Banana, Decl(typeVariableTypeGuards.ts, 11, 1)) + + color: 'yellow'; +>color : Symbol(Banana.color, Decl(typeVariableTypeGuards.ts, 15, 18)) +} + +class Monkey { +>Monkey : Symbol(Monkey, Decl(typeVariableTypeGuards.ts, 17, 1)) +>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 19, 13)) +>Banana : Symbol(Banana, Decl(typeVariableTypeGuards.ts, 11, 1)) + + a: T; +>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44)) +>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 19, 13)) + + render() { +>render : Symbol(Monkey.render, Decl(typeVariableTypeGuards.ts, 20, 9)) + + if (this.a) { +>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44)) +>this : Symbol(Monkey, Decl(typeVariableTypeGuards.ts, 17, 1)) +>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44)) + + this.a.color; +>this.a.color : Symbol(Banana.color, Decl(typeVariableTypeGuards.ts, 15, 18)) +>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44)) +>this : Symbol(Monkey, Decl(typeVariableTypeGuards.ts, 17, 1)) +>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44)) +>color : Symbol(Banana.color, Decl(typeVariableTypeGuards.ts, 15, 18)) + } + } +} + +interface BigBanana extends Banana { +>BigBanana : Symbol(BigBanana, Decl(typeVariableTypeGuards.ts, 26, 1)) +>Banana : Symbol(Banana, Decl(typeVariableTypeGuards.ts, 11, 1)) +} + +class BigMonkey extends Monkey { +>BigMonkey : Symbol(BigMonkey, Decl(typeVariableTypeGuards.ts, 29, 1)) +>Monkey : Symbol(Monkey, Decl(typeVariableTypeGuards.ts, 17, 1)) +>BigBanana : Symbol(BigBanana, Decl(typeVariableTypeGuards.ts, 26, 1)) + + render() { +>render : Symbol(BigMonkey.render, Decl(typeVariableTypeGuards.ts, 31, 43)) + + if (this.a) { +>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44)) +>this : Symbol(BigMonkey, Decl(typeVariableTypeGuards.ts, 29, 1)) +>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44)) + + this.a.color; +>this.a.color : Symbol(Banana.color, Decl(typeVariableTypeGuards.ts, 15, 18)) +>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44)) +>this : Symbol(BigMonkey, Decl(typeVariableTypeGuards.ts, 29, 1)) +>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44)) +>color : Symbol(Banana.color, Decl(typeVariableTypeGuards.ts, 15, 18)) + } + } +} + +// Another repro + +type Item = { +>Item : Symbol(Item, Decl(typeVariableTypeGuards.ts, 37, 1)) + + (): string; + x: string; +>x : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15)) +} + +function f1(obj: T) { +>f1 : Symbol(f1, Decl(typeVariableTypeGuards.ts, 44, 1)) +>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 46, 12)) +>Item : Symbol(Item, Decl(typeVariableTypeGuards.ts, 37, 1)) +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 46, 40)) +>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 46, 12)) + + if (obj) { +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 46, 40)) + + obj.x; +>obj.x : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15)) +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 46, 40)) +>x : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15)) + + obj["x"]; +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 46, 40)) +>"x" : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15)) + + obj(); +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 46, 40)) + } +} + +function f2(obj: T | undefined) { +>f2 : Symbol(f2, Decl(typeVariableTypeGuards.ts, 52, 1)) +>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 54, 12)) +>Item : Symbol(Item, Decl(typeVariableTypeGuards.ts, 37, 1)) +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 54, 40)) +>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 54, 12)) + + if (obj) { +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 54, 40)) + + obj.x; +>obj.x : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15)) +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 54, 40)) +>x : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15)) + + obj["x"]; +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 54, 40)) +>"x" : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15)) + + obj(); +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 54, 40)) + } +} + +function f3(obj: T | null) { +>f3 : Symbol(f3, Decl(typeVariableTypeGuards.ts, 60, 1)) +>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 62, 12)) +>Item : Symbol(Item, Decl(typeVariableTypeGuards.ts, 37, 1)) +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 62, 40)) +>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 62, 12)) + + if (obj) { +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 62, 40)) + + obj.x; +>obj.x : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15)) +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 62, 40)) +>x : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15)) + + obj["x"]; +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 62, 40)) +>"x" : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15)) + + obj(); +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 62, 40)) + } +} + +function f4(obj: T | undefined, x: number) { +>f4 : Symbol(f4, Decl(typeVariableTypeGuards.ts, 68, 1)) +>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 70, 12)) +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 70, 44)) +>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 70, 12)) +>x : Symbol(x, Decl(typeVariableTypeGuards.ts, 70, 63)) + + if (obj) { +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 70, 44)) + + obj[x].length; +>obj[x].length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 70, 44)) +>x : Symbol(x, Decl(typeVariableTypeGuards.ts, 70, 63)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + } +} + +function f5(obj: T | undefined, key: K) { +>f5 : Symbol(f5, Decl(typeVariableTypeGuards.ts, 74, 1)) +>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 76, 12)) +>K : Symbol(K, Decl(typeVariableTypeGuards.ts, 76, 14)) +>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 76, 12)) +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 76, 34)) +>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 76, 12)) +>key : Symbol(key, Decl(typeVariableTypeGuards.ts, 76, 53)) +>K : Symbol(K, Decl(typeVariableTypeGuards.ts, 76, 14)) + + if (obj) { +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 76, 34)) + + obj[key]; +>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 76, 34)) +>key : Symbol(key, Decl(typeVariableTypeGuards.ts, 76, 53)) + } +} + diff --git a/tests/baselines/reference/typeVariableTypeGuards.types b/tests/baselines/reference/typeVariableTypeGuards.types new file mode 100644 index 00000000000..bfcf851648a --- /dev/null +++ b/tests/baselines/reference/typeVariableTypeGuards.types @@ -0,0 +1,232 @@ +=== tests/cases/compiler/typeVariableTypeGuards.ts === +// Repro from #14091 + +interface Foo { +>Foo : Foo + + foo(): void +>foo : () => void +} + +class A

> { +>A : A

+>P : P +>Partial : Partial +>Foo : Foo + + props: Readonly

+>props : Readonly

+>Readonly : Readonly +>P : P + + doSomething() { +>doSomething : () => void + + this.props.foo && this.props.foo() +>this.props.foo && this.props.foo() : void +>this.props.foo : P["foo"] +>this.props : Readonly

+>this : this +>props : Readonly

+>foo : P["foo"] +>this.props.foo() : void +>this.props.foo : () => void +>this.props : Readonly

+>this : this +>props : Readonly

+>foo : () => void + } +} + +// Repro from #14415 + +interface Banana { +>Banana : Banana + + color: 'yellow'; +>color : "yellow" +} + +class Monkey { +>Monkey : Monkey +>T : T +>Banana : Banana + + a: T; +>a : T +>T : T + + render() { +>render : () => void + + if (this.a) { +>this.a : T +>this : this +>a : T + + this.a.color; +>this.a.color : "yellow" +>this.a : Banana +>this : this +>a : Banana +>color : "yellow" + } + } +} + +interface BigBanana extends Banana { +>BigBanana : BigBanana +>Banana : Banana +} + +class BigMonkey extends Monkey { +>BigMonkey : BigMonkey +>Monkey : Monkey +>BigBanana : BigBanana + + render() { +>render : () => void + + if (this.a) { +>this.a : BigBanana +>this : this +>a : BigBanana + + this.a.color; +>this.a.color : "yellow" +>this.a : BigBanana +>this : this +>a : BigBanana +>color : "yellow" + } + } +} + +// Another repro + +type Item = { +>Item : Item + + (): string; + x: string; +>x : string +} + +function f1(obj: T) { +>f1 : (obj: T) => void +>T : T +>Item : Item +>obj : T +>T : T + + if (obj) { +>obj : T + + obj.x; +>obj.x : string +>obj : Item +>x : string + + obj["x"]; +>obj["x"] : string +>obj : Item +>"x" : "x" + + obj(); +>obj() : string +>obj : Item + } +} + +function f2(obj: T | undefined) { +>f2 : (obj: T | undefined) => void +>T : T +>Item : Item +>obj : T | undefined +>T : T + + if (obj) { +>obj : T | undefined + + obj.x; +>obj.x : string +>obj : Item +>x : string + + obj["x"]; +>obj["x"] : string +>obj : Item +>"x" : "x" + + obj(); +>obj() : string +>obj : Item + } +} + +function f3(obj: T | null) { +>f3 : (obj: T | null) => void +>T : T +>Item : Item +>obj : T | null +>T : T +>null : null + + if (obj) { +>obj : T | null + + obj.x; +>obj.x : string +>obj : Item +>x : string + + obj["x"]; +>obj["x"] : string +>obj : Item +>"x" : "x" + + obj(); +>obj() : string +>obj : Item + } +} + +function f4(obj: T | undefined, x: number) { +>f4 : (obj: T | undefined, x: number) => void +>T : T +>obj : T | undefined +>T : T +>x : number + + if (obj) { +>obj : T | undefined + + obj[x].length; +>obj[x].length : number +>obj[x] : string +>obj : string[] +>x : number +>length : number + } +} + +function f5(obj: T | undefined, key: K) { +>f5 : (obj: T | undefined, key: K) => void +>T : T +>K : K +>T : T +>obj : T | undefined +>T : T +>key : K +>K : K + + if (obj) { +>obj : T | undefined + + obj[key]; +>obj[key] : T[K] +>obj : T +>key : K + } +} + diff --git a/tests/cases/compiler/capturedVarInLoop.ts b/tests/cases/compiler/capturedVarInLoop.ts new file mode 100644 index 00000000000..65cc5620f83 --- /dev/null +++ b/tests/cases/compiler/capturedVarInLoop.ts @@ -0,0 +1,6 @@ +// @target: es5 +for (var i = 0; i < 10; i++) { + var str = 'x', len = str.length; + let lambda1 = (y) => { }; + let lambda2 = () => lambda1(len); +} \ No newline at end of file diff --git a/tests/cases/compiler/checkIndexConstraintOfJavascriptClassExpression.ts b/tests/cases/compiler/checkIndexConstraintOfJavascriptClassExpression.ts index 8de18a69536..58844d98fd8 100644 --- a/tests/cases/compiler/checkIndexConstraintOfJavascriptClassExpression.ts +++ b/tests/cases/compiler/checkIndexConstraintOfJavascriptClassExpression.ts @@ -1,10 +1,19 @@ // @Filename: weird.js // @allowJs: true +// @checkJs: true +// @strict: true +// @noEmit: true // @out: foo.js someFunction(function(BaseClass) { - class Hello extends BaseClass { - constructor() { - this.foo = "bar"; - } - } + 'use strict'; + const DEFAULT_MESSAGE = "nop!"; + class Hello extends BaseClass { + constructor() { + super(); + this.foo = "bar"; + } + _render(error) { + const message = error.message || DEFAULT_MESSAGE; + } + } }); diff --git a/tests/cases/compiler/typeVariableTypeGuards.ts b/tests/cases/compiler/typeVariableTypeGuards.ts new file mode 100644 index 00000000000..0a4221c93a0 --- /dev/null +++ b/tests/cases/compiler/typeVariableTypeGuards.ts @@ -0,0 +1,83 @@ +// @strict: true + +// Repro from #14091 + +interface Foo { + foo(): void +} + +class A

> { + props: Readonly

+ doSomething() { + this.props.foo && this.props.foo() + } +} + +// Repro from #14415 + +interface Banana { + color: 'yellow'; +} + +class Monkey { + a: T; + render() { + if (this.a) { + this.a.color; + } + } +} + +interface BigBanana extends Banana { +} + +class BigMonkey extends Monkey { + render() { + if (this.a) { + this.a.color; + } + } +} + +// Another repro + +type Item = { + (): string; + x: string; +} + +function f1(obj: T) { + if (obj) { + obj.x; + obj["x"]; + obj(); + } +} + +function f2(obj: T | undefined) { + if (obj) { + obj.x; + obj["x"]; + obj(); + } +} + +function f3(obj: T | null) { + if (obj) { + obj.x; + obj["x"]; + obj(); + } +} + +function f4(obj: T | undefined, x: number) { + if (obj) { + obj[x].length; + } +} + +function f5(obj: T | undefined, key: K) { + if (obj) { + obj[key]; + } +} diff --git a/tests/cases/conformance/jsx/checkJsxChildrenProperty12.tsx b/tests/cases/conformance/jsx/checkJsxChildrenProperty12.tsx new file mode 100644 index 00000000000..e49b196b8f8 --- /dev/null +++ b/tests/cases/conformance/jsx/checkJsxChildrenProperty12.tsx @@ -0,0 +1,36 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface ButtonProp { + a: number, + b: string, + children: Button; +} + +class Button extends React.Component { + render() { + let condition: boolean; + if (condition) { + return + } + else { + return ( +

Hello World
+
); + } + } +} + +interface InnerButtonProp { + a: number +} + +class InnerButton extends React.Component { + render() { + return (); + } +} diff --git a/tests/cases/conformance/jsx/checkJsxChildrenProperty13.tsx b/tests/cases/conformance/jsx/checkJsxChildrenProperty13.tsx new file mode 100644 index 00000000000..1584bf43159 --- /dev/null +++ b/tests/cases/conformance/jsx/checkJsxChildrenProperty13.tsx @@ -0,0 +1,31 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface ButtonProp { + a: number, + b: string, + children: Button; +} + +class Button extends React.Component { + render() { + // Error children are specified twice + return ( +
Hello World
+
); + } +} + +interface InnerButtonProp { + a: number +} + +class InnerButton extends React.Component { + render() { + return (); + } +} diff --git a/tests/cases/conformance/jsx/tsxAttributeResolution3.tsx b/tests/cases/conformance/jsx/tsxAttributeResolution3.tsx index 0f968dd0a5c..d63cf8e4acc 100644 --- a/tests/cases/conformance/jsx/tsxAttributeResolution3.tsx +++ b/tests/cases/conformance/jsx/tsxAttributeResolution3.tsx @@ -32,7 +32,7 @@ var obj4 = { x: 32, y: 32 }; var obj5 = { x: 32, y: 32 }; -// Error +// Ok var obj6 = { x: 'ok', y: 32, extra: 100 }; diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution12.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution12.tsx index b5150bd27ff..457a3f29810 100644 --- a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution12.tsx +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution12.tsx @@ -32,3 +32,5 @@ let anyobj: any; let x = let x1 = let x2 = +let x3 = + diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution13.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution13.tsx new file mode 100644 index 00000000000..b665654514c --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution13.tsx @@ -0,0 +1,33 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface ComponentProps { + property1: string; + property2: number; +} + +export default function Component(props: ComponentProps) { + let condition1: boolean; + if (condition1) { + return ( + + ); + } + else { + return (); + } +} + +interface AnotherComponentProps { + property1: string; +} + +function ChildComponent({ property1 }: AnotherComponentProps) { + return ( + {property1} + ); +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution14.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution14.tsx new file mode 100644 index 00000000000..b9edcc8ab75 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution14.tsx @@ -0,0 +1,28 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface ComponentProps { + property1: string; + property2: number; +} + +export default function Component(props: ComponentProps) { + return ( + // Error extra property + + ); +} + +interface AnotherComponentProps { + property1: string; +} + +function AnotherComponent({ property1 }: AnotherComponentProps) { + return ( + {property1} + ); +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution15.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution15.tsx new file mode 100644 index 00000000000..5ede01c0eab --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution15.tsx @@ -0,0 +1,29 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface ComponentProps { + property1: string; + property2: number; +} + +export default function Component(props: ComponentProps) { + return ( + + ); +} + +interface AnotherComponentProps { + property1: string; + AnotherProperty1: string; + property2: boolean; +} + +function AnotherComponent({ property1 }: AnotherComponentProps) { + return ( + {property1} + ); +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution16.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution16.tsx new file mode 100644 index 00000000000..98616661857 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution16.tsx @@ -0,0 +1,30 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface ComponentProps { + property1: string; + property2: number; +} + +export default function Component(props: ComponentProps) { + return ( + // Error: missing property + + ); +} + +interface AnotherComponentProps { + property1: string; + AnotherProperty1: string; + property2: boolean; +} + +function AnotherComponent({ property1 }: AnotherComponentProps) { + return ( + {property1} + ); +} \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution2.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution2.tsx index 1d647226ade..7ec1d871189 100644 --- a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution2.tsx +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution2.tsx @@ -21,4 +21,6 @@ const obj = {}; // Error let p = ; let y = ; -let z = ; \ No newline at end of file +let z = ; +let w = ; +let w1 = ; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution5.tsx b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution5.tsx index e050932b1db..22045c81451 100644 --- a/tests/cases/conformance/jsx/tsxSpreadAttributesResolution5.tsx +++ b/tests/cases/conformance/jsx/tsxSpreadAttributesResolution5.tsx @@ -34,5 +34,5 @@ class EmptyProp extends React.Component<{}, {}> { let o = { prop1: false } -// Error +// Ok let e = ; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload4.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload4.tsx index 7700fed6902..b96073b4cc0 100644 --- a/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload4.tsx +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponentOverload4.tsx @@ -18,7 +18,7 @@ let obj2: any; const c0 = ; // extra property; const c1 = ; // missing property; const c2 = ; // type incompatible; -const c3 = ; // Extra attribute; +const c3 = ; // This is OK becuase all attribute are spread const c4 = ; // extra property; const c5 = ; // type incompatible; const c6 = ; // Should error as there is extra attribute that doesn't match any. Current it is not diff --git a/tests/cases/conformance/jsx/tsxStatelessFunctionComponents1.tsx b/tests/cases/conformance/jsx/tsxStatelessFunctionComponents1.tsx index 8990cb3c8b0..b486a72ce15 100644 --- a/tests/cases/conformance/jsx/tsxStatelessFunctionComponents1.tsx +++ b/tests/cases/conformance/jsx/tsxStatelessFunctionComponents1.tsx @@ -46,7 +46,7 @@ let o = { prop1: true; } -// Error +// OK as access properties are allow when spread let i2 = let o1: any; diff --git a/tests/cases/fourslash/completionInJsDoc.ts b/tests/cases/fourslash/completionInJsDoc.ts index 60707905956..4c1bb004671 100644 --- a/tests/cases/fourslash/completionInJsDoc.ts +++ b/tests/cases/fourslash/completionInJsDoc.ts @@ -84,23 +84,18 @@ goTo.marker('8'); verify.completionListContains('number'); goTo.marker('9'); -verify.completionListCount(40); verify.completionListContains("@argument"); goTo.marker('10'); -verify.completionListCount(40); verify.completionListContains("@returns"); goTo.marker('11'); -verify.completionListCount(40); verify.completionListContains("@argument"); goTo.marker('12'); -verify.completionListCount(40); verify.completionListContains("@constructor"); goTo.marker('13'); -verify.completionListCount(40); verify.completionListContains("@param"); goTo.marker('14'); diff --git a/tests/cases/fourslash/completionsKeyof.ts b/tests/cases/fourslash/completionsKeyof.ts new file mode 100644 index 00000000000..e3beae556c5 --- /dev/null +++ b/tests/cases/fourslash/completionsKeyof.ts @@ -0,0 +1,17 @@ +/// + +////interface A { a: number; }; +////interface B { a: number; b: number; }; +////function f(key: T) {} +////f("/*f*/"); +////function g(key: T) {} +////g("/*g*/"); + +goTo.marker("f"); +verify.completionListCount(1); +verify.completionListContains("a"); + +goTo.marker("g"); +verify.completionListCount(2); +verify.completionListContains("a"); +verify.completionListContains("b");