From bdcc4eb988786fb80d21b0667b2b68b2de5c6bbc Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 9 Jul 2015 21:44:56 -0700 Subject: [PATCH] Implementation for weak types --- src/compiler/checker.ts | 24 +++++++++++++++++++ .../diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 ++++ src/server/editorServices.ts | 2 +- 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2b57aca48ac..07265cf9462 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4785,9 +4785,14 @@ namespace ts { let result = Ternary.True; let properties = getPropertiesOfObjectType(target); let requireOptionalProperties = relation === subtypeRelation && !(source.flags & TypeFlags.ObjectLiteral); + let foundMatchingProperty = !isWeak(target); for (let targetProp of properties) { let sourceProp = getPropertyOfType(source, targetProp.name); + if (sourceProp) { + foundMatchingProperty = true; + } + if (sourceProp !== targetProp) { if (!sourceProp) { if (!(targetProp.flags & SymbolFlags.Optional) || requireOptionalProperties) { @@ -4859,6 +4864,14 @@ namespace ts { } } } + + if (!foundMatchingProperty && getPropertiesOfType(source).length > 0) { + if (reportErrors) { + reportError(Diagnostics.Weak_type_0_has_no_properties_in_common_with_1, typeToString(target), typeToString(source)); + } + return Ternary.False; + } + return result; } @@ -5121,6 +5134,17 @@ namespace ts { return false; } + // A type is 'weak' if it is an object type with at least one optional property + // and no required properties or index signatures + function isWeak(type: Type) { + let props = getPropertiesOfType(type); + return type.flags & TypeFlags.ObjectType && + props.length > 0 && + !forEach(props, p => !(p.flags & SymbolFlags.Optional)) && + !getIndexTypeOfType(type, IndexKind.String) && + !getIndexTypeOfType(type, IndexKind.Number); + } + function isPropertyIdenticalTo(sourceProp: Symbol, targetProp: Symbol): boolean { return compareProperties(sourceProp, targetProp, compareTypes) !== Ternary.False; } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index a17f8857590..12b257eac34 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -414,6 +414,7 @@ namespace ts { The_arguments_object_cannot_be_referenced_in_an_async_arrow_function_Consider_using_a_standard_async_function_expression: { code: 2522, category: DiagnosticCategory.Error, key: "The 'arguments' object cannot be referenced in an async arrow function. Consider using a standard async function expression." }, yield_expressions_cannot_be_used_in_a_parameter_initializer: { code: 2523, category: DiagnosticCategory.Error, key: "'yield' expressions cannot be used in a parameter initializer." }, await_expressions_cannot_be_used_in_a_parameter_initializer: { code: 2524, category: DiagnosticCategory.Error, key: "'await' expressions cannot be used in a parameter initializer." }, + Weak_type_0_has_no_properties_in_common_with_1: { code: 2525, category: DiagnosticCategory.Error, key: "Weak type '{0}' has no properties in common with '{1}'." }, JSX_element_attributes_type_0_must_be_an_object_type: { code: 2600, category: DiagnosticCategory.Error, key: "JSX element attributes type '{0}' must be an object type." }, The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: { code: 2601, category: DiagnosticCategory.Error, key: "The return type of a JSX element constructor must return an object type." }, JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: { code: 2602, category: DiagnosticCategory.Error, key: "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 94be4f53c97..59c856e87d2 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1645,6 +1645,10 @@ "category": "Error", "code": 2524 }, + "Weak type '{0}' has no properties in common with '{1}'.": { + "category": "Error", + "code": 2525 + }, "JSX element attributes type '{0}' must be an object type.": { "category": "Error", "code": 2600 diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 91d400ff263..04cad877561 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -912,7 +912,7 @@ namespace ts.server { var dirPath = ts.getDirectoryPath(configFilename); var rawConfig: { config?: ProjectOptions; error?: Diagnostic; } = ts.readConfigFile(configFilename); if (rawConfig.error) { - return rawConfig.error; + return { errorMsg: ts.flattenDiagnosticMessageText(rawConfig.error.messageText, '\n') }; } else { var parsedCommandLine = ts.parseConfigFile(rawConfig.config, this.host, dirPath);