From ffed2484d37ed60d894834731e592c48a7a9b29e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 12 Nov 2016 12:46:01 -0800 Subject: [PATCH 1/4] Added tests. --- .../comparable/optionalProperties01.ts | 11 +++++++++++ .../comparable/optionalProperties02.ts | 9 +++++++++ 2 files changed, 20 insertions(+) create mode 100644 tests/cases/conformance/types/typeRelationships/comparable/optionalProperties01.ts create mode 100644 tests/cases/conformance/types/typeRelationships/comparable/optionalProperties02.ts diff --git a/tests/cases/conformance/types/typeRelationships/comparable/optionalProperties01.ts b/tests/cases/conformance/types/typeRelationships/comparable/optionalProperties01.ts new file mode 100644 index 0000000000000..d4f04d78c8062 --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/comparable/optionalProperties01.ts @@ -0,0 +1,11 @@ +// @strictNullChecks: true +// @declaration: true + +interface Foo { + required1: string; + required2: string; + optional?: string; +} + +const foo1 = { required1: "hello" } as Foo; +const foo2 = { required1: "hello", optional: "bar" } as Foo; diff --git a/tests/cases/conformance/types/typeRelationships/comparable/optionalProperties02.ts b/tests/cases/conformance/types/typeRelationships/comparable/optionalProperties02.ts new file mode 100644 index 0000000000000..21f83276d449e --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/comparable/optionalProperties02.ts @@ -0,0 +1,9 @@ +// @strictNullChecks: true +// @declaration: true + +interface Foo { + a?: string; + b: string; +} + +{ a: undefined }; \ No newline at end of file From 2edabe0ae0b40a12c7732f690eeb8517631f9a6b Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 12 Nov 2016 12:53:23 -0800 Subject: [PATCH 2/4] Accepted baselines. --- .../reference/optionalProperties01.errors.txt | 18 +++++++++++++ .../reference/optionalProperties01.js | 25 +++++++++++++++++++ .../reference/optionalProperties02.errors.txt | 15 +++++++++++ .../reference/optionalProperties02.js | 18 +++++++++++++ 4 files changed, 76 insertions(+) create mode 100644 tests/baselines/reference/optionalProperties01.errors.txt create mode 100644 tests/baselines/reference/optionalProperties01.js create mode 100644 tests/baselines/reference/optionalProperties02.errors.txt create mode 100644 tests/baselines/reference/optionalProperties02.js diff --git a/tests/baselines/reference/optionalProperties01.errors.txt b/tests/baselines/reference/optionalProperties01.errors.txt new file mode 100644 index 0000000000000..c44829b20a70b --- /dev/null +++ b/tests/baselines/reference/optionalProperties01.errors.txt @@ -0,0 +1,18 @@ +tests/cases/conformance/types/typeRelationships/comparable/optionalProperties01.ts(9,14): error TS2352: Type '{ required1: string; optional: string; }' cannot be converted to type 'Foo'. + Property 'required2' is missing in type '{ required1: string; optional: string; }'. + + +==== tests/cases/conformance/types/typeRelationships/comparable/optionalProperties01.ts (1 errors) ==== + + interface Foo { + required1: string; + required2: string; + optional?: string; + } + + const foo1 = { required1: "hello" } as Foo; + const foo2 = { required1: "hello", optional: "bar" } as Foo; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2352: Type '{ required1: string; optional: string; }' cannot be converted to type 'Foo'. +!!! error TS2352: Property 'required2' is missing in type '{ required1: string; optional: string; }'. + \ No newline at end of file diff --git a/tests/baselines/reference/optionalProperties01.js b/tests/baselines/reference/optionalProperties01.js new file mode 100644 index 0000000000000..a614b9e7e37c1 --- /dev/null +++ b/tests/baselines/reference/optionalProperties01.js @@ -0,0 +1,25 @@ +//// [optionalProperties01.ts] + +interface Foo { + required1: string; + required2: string; + optional?: string; +} + +const foo1 = { required1: "hello" } as Foo; +const foo2 = { required1: "hello", optional: "bar" } as Foo; + + +//// [optionalProperties01.js] +var foo1 = { required1: "hello" }; +var foo2 = { required1: "hello", optional: "bar" }; + + +//// [optionalProperties01.d.ts] +interface Foo { + required1: string; + required2: string; + optional?: string; +} +declare const foo1: Foo; +declare const foo2: Foo; diff --git a/tests/baselines/reference/optionalProperties02.errors.txt b/tests/baselines/reference/optionalProperties02.errors.txt new file mode 100644 index 0000000000000..fefcf1eb95fa2 --- /dev/null +++ b/tests/baselines/reference/optionalProperties02.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/types/typeRelationships/comparable/optionalProperties02.ts(7,1): error TS2352: Type '{ a: undefined; }' cannot be converted to type 'Foo'. + Property 'b' is missing in type '{ a: undefined; }'. + + +==== tests/cases/conformance/types/typeRelationships/comparable/optionalProperties02.ts (1 errors) ==== + + interface Foo { + a?: string; + b: string; + } + + { a: undefined }; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2352: Type '{ a: undefined; }' cannot be converted to type 'Foo'. +!!! error TS2352: Property 'b' is missing in type '{ a: undefined; }'. \ No newline at end of file diff --git a/tests/baselines/reference/optionalProperties02.js b/tests/baselines/reference/optionalProperties02.js new file mode 100644 index 0000000000000..f632c5d67a8ed --- /dev/null +++ b/tests/baselines/reference/optionalProperties02.js @@ -0,0 +1,18 @@ +//// [optionalProperties02.ts] + +interface Foo { + a?: string; + b: string; +} + +{ a: undefined }; + +//// [optionalProperties02.js] +({ a: undefined }); + + +//// [optionalProperties02.d.ts] +interface Foo { + a?: string; + b: string; +} From 375437ef3cb149d49b560b0b30aa5c305b9c6eaa Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 12 Nov 2016 12:59:43 -0800 Subject: [PATCH 3/4] Avoid checking for optionality in comparability checks. --- src/compiler/checker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 789f2bd81046f..6be5c1c453fb5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7331,7 +7331,8 @@ namespace ts { return Ternary.False; } result &= related; - if (sourceProp.flags & SymbolFlags.Optional && !(targetProp.flags & SymbolFlags.Optional)) { + // When checking for comparability, be more lenient with optional properties. + if (relation !== comparableRelation && sourceProp.flags & SymbolFlags.Optional && !(targetProp.flags & SymbolFlags.Optional)) { // TypeScript 1.0 spec (April 2014): 3.8.3 // S is a subtype of a type T, and T is a supertype of S if ... // S' and T are object types and, for each member M in T.. From 8708c8965cbc71496bdb1f232cd6b38061353405 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 12 Nov 2016 12:59:57 -0800 Subject: [PATCH 4/4] Accepted baselines. --- .../reference/optionalProperties01.errors.txt | 18 ---------- .../reference/optionalProperties01.symbols | 26 +++++++++++++++ .../reference/optionalProperties01.types | 33 +++++++++++++++++++ .../reference/optionalProperties02.errors.txt | 15 --------- .../reference/optionalProperties02.symbols | 17 ++++++++++ .../reference/optionalProperties02.types | 19 +++++++++++ 6 files changed, 95 insertions(+), 33 deletions(-) delete mode 100644 tests/baselines/reference/optionalProperties01.errors.txt create mode 100644 tests/baselines/reference/optionalProperties01.symbols create mode 100644 tests/baselines/reference/optionalProperties01.types delete mode 100644 tests/baselines/reference/optionalProperties02.errors.txt create mode 100644 tests/baselines/reference/optionalProperties02.symbols create mode 100644 tests/baselines/reference/optionalProperties02.types diff --git a/tests/baselines/reference/optionalProperties01.errors.txt b/tests/baselines/reference/optionalProperties01.errors.txt deleted file mode 100644 index c44829b20a70b..0000000000000 --- a/tests/baselines/reference/optionalProperties01.errors.txt +++ /dev/null @@ -1,18 +0,0 @@ -tests/cases/conformance/types/typeRelationships/comparable/optionalProperties01.ts(9,14): error TS2352: Type '{ required1: string; optional: string; }' cannot be converted to type 'Foo'. - Property 'required2' is missing in type '{ required1: string; optional: string; }'. - - -==== tests/cases/conformance/types/typeRelationships/comparable/optionalProperties01.ts (1 errors) ==== - - interface Foo { - required1: string; - required2: string; - optional?: string; - } - - const foo1 = { required1: "hello" } as Foo; - const foo2 = { required1: "hello", optional: "bar" } as Foo; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2352: Type '{ required1: string; optional: string; }' cannot be converted to type 'Foo'. -!!! error TS2352: Property 'required2' is missing in type '{ required1: string; optional: string; }'. - \ No newline at end of file diff --git a/tests/baselines/reference/optionalProperties01.symbols b/tests/baselines/reference/optionalProperties01.symbols new file mode 100644 index 0000000000000..95c53626f6e85 --- /dev/null +++ b/tests/baselines/reference/optionalProperties01.symbols @@ -0,0 +1,26 @@ +=== tests/cases/conformance/types/typeRelationships/comparable/optionalProperties01.ts === + +interface Foo { +>Foo : Symbol(Foo, Decl(optionalProperties01.ts, 0, 0)) + + required1: string; +>required1 : Symbol(Foo.required1, Decl(optionalProperties01.ts, 1, 15)) + + required2: string; +>required2 : Symbol(Foo.required2, Decl(optionalProperties01.ts, 2, 20)) + + optional?: string; +>optional : Symbol(Foo.optional, Decl(optionalProperties01.ts, 3, 20)) +} + +const foo1 = { required1: "hello" } as Foo; +>foo1 : Symbol(foo1, Decl(optionalProperties01.ts, 7, 5)) +>required1 : Symbol(required1, Decl(optionalProperties01.ts, 7, 14)) +>Foo : Symbol(Foo, Decl(optionalProperties01.ts, 0, 0)) + +const foo2 = { required1: "hello", optional: "bar" } as Foo; +>foo2 : Symbol(foo2, Decl(optionalProperties01.ts, 8, 5)) +>required1 : Symbol(required1, Decl(optionalProperties01.ts, 8, 14)) +>optional : Symbol(optional, Decl(optionalProperties01.ts, 8, 34)) +>Foo : Symbol(Foo, Decl(optionalProperties01.ts, 0, 0)) + diff --git a/tests/baselines/reference/optionalProperties01.types b/tests/baselines/reference/optionalProperties01.types new file mode 100644 index 0000000000000..20d16d4071e69 --- /dev/null +++ b/tests/baselines/reference/optionalProperties01.types @@ -0,0 +1,33 @@ +=== tests/cases/conformance/types/typeRelationships/comparable/optionalProperties01.ts === + +interface Foo { +>Foo : Foo + + required1: string; +>required1 : string + + required2: string; +>required2 : string + + optional?: string; +>optional : string | undefined +} + +const foo1 = { required1: "hello" } as Foo; +>foo1 : Foo +>{ required1: "hello" } as Foo : Foo +>{ required1: "hello" } : { required1: string; } +>required1 : string +>"hello" : "hello" +>Foo : Foo + +const foo2 = { required1: "hello", optional: "bar" } as Foo; +>foo2 : Foo +>{ required1: "hello", optional: "bar" } as Foo : Foo +>{ required1: "hello", optional: "bar" } : { required1: string; optional: string; } +>required1 : string +>"hello" : "hello" +>optional : string +>"bar" : "bar" +>Foo : Foo + diff --git a/tests/baselines/reference/optionalProperties02.errors.txt b/tests/baselines/reference/optionalProperties02.errors.txt deleted file mode 100644 index fefcf1eb95fa2..0000000000000 --- a/tests/baselines/reference/optionalProperties02.errors.txt +++ /dev/null @@ -1,15 +0,0 @@ -tests/cases/conformance/types/typeRelationships/comparable/optionalProperties02.ts(7,1): error TS2352: Type '{ a: undefined; }' cannot be converted to type 'Foo'. - Property 'b' is missing in type '{ a: undefined; }'. - - -==== tests/cases/conformance/types/typeRelationships/comparable/optionalProperties02.ts (1 errors) ==== - - interface Foo { - a?: string; - b: string; - } - - { a: undefined }; - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2352: Type '{ a: undefined; }' cannot be converted to type 'Foo'. -!!! error TS2352: Property 'b' is missing in type '{ a: undefined; }'. \ No newline at end of file diff --git a/tests/baselines/reference/optionalProperties02.symbols b/tests/baselines/reference/optionalProperties02.symbols new file mode 100644 index 0000000000000..b88f9ad742982 --- /dev/null +++ b/tests/baselines/reference/optionalProperties02.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/types/typeRelationships/comparable/optionalProperties02.ts === + +interface Foo { +>Foo : Symbol(Foo, Decl(optionalProperties02.ts, 0, 0)) + + a?: string; +>a : Symbol(Foo.a, Decl(optionalProperties02.ts, 1, 15)) + + b: string; +>b : Symbol(Foo.b, Decl(optionalProperties02.ts, 2, 15)) +} + +{ a: undefined }; +>Foo : Symbol(Foo, Decl(optionalProperties02.ts, 0, 0)) +>a : Symbol(a, Decl(optionalProperties02.ts, 6, 6)) +>undefined : Symbol(undefined) + diff --git a/tests/baselines/reference/optionalProperties02.types b/tests/baselines/reference/optionalProperties02.types new file mode 100644 index 0000000000000..05e979b397288 --- /dev/null +++ b/tests/baselines/reference/optionalProperties02.types @@ -0,0 +1,19 @@ +=== tests/cases/conformance/types/typeRelationships/comparable/optionalProperties02.ts === + +interface Foo { +>Foo : Foo + + a?: string; +>a : string | undefined + + b: string; +>b : string +} + +{ a: undefined }; +>{ a: undefined } : Foo +>Foo : Foo +>{ a: undefined } : { a: undefined; } +>a : undefined +>undefined : undefined +