Fix assignment of intersections to objects with optional properties (#37195)
* Treat intersections of only objects as a single object in relations * Exclude intersections containing non-inferrable types * Accept new baselines * Update test * Accept new baselines * Add tests
This commit is contained in:
parent
ad8d3d90a5
commit
b8baf48043
|
@ -15415,7 +15415,9 @@ namespace ts {
|
||||||
//
|
//
|
||||||
// - For a primitive type or type parameter (such as 'number = A & B') there is no point in
|
// - For a primitive type or type parameter (such as 'number = A & B') there is no point in
|
||||||
// breaking the intersection apart.
|
// breaking the intersection apart.
|
||||||
result = someTypeRelatedToType(<IntersectionType>source, target, /*reportErrors*/ false, IntersectionState.Source);
|
if (!isNonGenericObjectType(target) || !every((<IntersectionType>source).types, t => isNonGenericObjectType(t) && !(getObjectFlags(t) & ObjectFlags.NonInferrableType))) {
|
||||||
|
result = someTypeRelatedToType(<IntersectionType>source, target, /*reportErrors*/ false, IntersectionState.Source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!result && (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable)) {
|
if (!result && (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable)) {
|
||||||
if (result = recursiveTypeRelatedTo(source, target, reportErrors, intersectionState)) {
|
if (result = recursiveTypeRelatedTo(source, target, reportErrors, intersectionState)) {
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
tests/cases/compiler/intersectionsAndOptionalProperties.ts(5,1): error TS2322: Type '{ a: null; b: string; }' is not assignable to type '{ a?: number | undefined; b: string; }'.
|
||||||
|
Types of property 'a' are incompatible.
|
||||||
|
Type 'null' is not assignable to type 'number | undefined'.
|
||||||
|
tests/cases/compiler/intersectionsAndOptionalProperties.ts(6,1): error TS2322: Type '{ a: null; } & { b: string; }' is not assignable to type '{ a?: number | undefined; b: string; }'.
|
||||||
|
Types of property 'a' are incompatible.
|
||||||
|
Type 'null' is not assignable to type 'number | undefined'.
|
||||||
|
tests/cases/compiler/intersectionsAndOptionalProperties.ts(19,5): error TS2322: Type 'From' is not assignable to type 'To'.
|
||||||
|
Types of property 'field' are incompatible.
|
||||||
|
Type 'null' is not assignable to type 'number | undefined'.
|
||||||
|
tests/cases/compiler/intersectionsAndOptionalProperties.ts(20,5): error TS2322: Type 'null' is not assignable to type 'number | undefined'.
|
||||||
|
|
||||||
|
|
||||||
|
==== tests/cases/compiler/intersectionsAndOptionalProperties.ts (4 errors) ====
|
||||||
|
declare let x: { a?: number, b: string };
|
||||||
|
declare let y: { a: null, b: string };
|
||||||
|
declare let z: { a: null } & { b: string };
|
||||||
|
|
||||||
|
x = y; // Error
|
||||||
|
~
|
||||||
|
!!! error TS2322: Type '{ a: null; b: string; }' is not assignable to type '{ a?: number | undefined; b: string; }'.
|
||||||
|
!!! error TS2322: Types of property 'a' are incompatible.
|
||||||
|
!!! error TS2322: Type 'null' is not assignable to type 'number | undefined'.
|
||||||
|
x = z; // Error
|
||||||
|
~
|
||||||
|
!!! error TS2322: Type '{ a: null; } & { b: string; }' is not assignable to type '{ a?: number | undefined; b: string; }'.
|
||||||
|
!!! error TS2322: Types of property 'a' are incompatible.
|
||||||
|
!!! error TS2322: Type 'null' is not assignable to type 'number | undefined'.
|
||||||
|
|
||||||
|
// Repro from #36604
|
||||||
|
|
||||||
|
interface To {
|
||||||
|
field?: number;
|
||||||
|
anotherField: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type From = { field: null } & Omit<To, 'field'>;
|
||||||
|
|
||||||
|
function foo(v: From) {
|
||||||
|
let x: To;
|
||||||
|
x = v; // Error
|
||||||
|
~
|
||||||
|
!!! error TS2322: Type 'From' is not assignable to type 'To'.
|
||||||
|
!!! error TS2322: Types of property 'field' are incompatible.
|
||||||
|
!!! error TS2322: Type 'null' is not assignable to type 'number | undefined'.
|
||||||
|
x.field = v.field; // Error
|
||||||
|
~~~~~~~
|
||||||
|
!!! error TS2322: Type 'null' is not assignable to type 'number | undefined'.
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
//// [intersectionsAndOptionalProperties.ts]
|
||||||
|
declare let x: { a?: number, b: string };
|
||||||
|
declare let y: { a: null, b: string };
|
||||||
|
declare let z: { a: null } & { b: string };
|
||||||
|
|
||||||
|
x = y; // Error
|
||||||
|
x = z; // Error
|
||||||
|
|
||||||
|
// Repro from #36604
|
||||||
|
|
||||||
|
interface To {
|
||||||
|
field?: number;
|
||||||
|
anotherField: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type From = { field: null } & Omit<To, 'field'>;
|
||||||
|
|
||||||
|
function foo(v: From) {
|
||||||
|
let x: To;
|
||||||
|
x = v; // Error
|
||||||
|
x.field = v.field; // Error
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// [intersectionsAndOptionalProperties.js]
|
||||||
|
"use strict";
|
||||||
|
x = y; // Error
|
||||||
|
x = z; // Error
|
||||||
|
function foo(v) {
|
||||||
|
var x;
|
||||||
|
x = v; // Error
|
||||||
|
x.field = v.field; // Error
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
=== tests/cases/compiler/intersectionsAndOptionalProperties.ts ===
|
||||||
|
declare let x: { a?: number, b: string };
|
||||||
|
>x : Symbol(x, Decl(intersectionsAndOptionalProperties.ts, 0, 11))
|
||||||
|
>a : Symbol(a, Decl(intersectionsAndOptionalProperties.ts, 0, 16))
|
||||||
|
>b : Symbol(b, Decl(intersectionsAndOptionalProperties.ts, 0, 28))
|
||||||
|
|
||||||
|
declare let y: { a: null, b: string };
|
||||||
|
>y : Symbol(y, Decl(intersectionsAndOptionalProperties.ts, 1, 11))
|
||||||
|
>a : Symbol(a, Decl(intersectionsAndOptionalProperties.ts, 1, 16))
|
||||||
|
>b : Symbol(b, Decl(intersectionsAndOptionalProperties.ts, 1, 25))
|
||||||
|
|
||||||
|
declare let z: { a: null } & { b: string };
|
||||||
|
>z : Symbol(z, Decl(intersectionsAndOptionalProperties.ts, 2, 11))
|
||||||
|
>a : Symbol(a, Decl(intersectionsAndOptionalProperties.ts, 2, 16))
|
||||||
|
>b : Symbol(b, Decl(intersectionsAndOptionalProperties.ts, 2, 30))
|
||||||
|
|
||||||
|
x = y; // Error
|
||||||
|
>x : Symbol(x, Decl(intersectionsAndOptionalProperties.ts, 0, 11))
|
||||||
|
>y : Symbol(y, Decl(intersectionsAndOptionalProperties.ts, 1, 11))
|
||||||
|
|
||||||
|
x = z; // Error
|
||||||
|
>x : Symbol(x, Decl(intersectionsAndOptionalProperties.ts, 0, 11))
|
||||||
|
>z : Symbol(z, Decl(intersectionsAndOptionalProperties.ts, 2, 11))
|
||||||
|
|
||||||
|
// Repro from #36604
|
||||||
|
|
||||||
|
interface To {
|
||||||
|
>To : Symbol(To, Decl(intersectionsAndOptionalProperties.ts, 5, 6))
|
||||||
|
|
||||||
|
field?: number;
|
||||||
|
>field : Symbol(To.field, Decl(intersectionsAndOptionalProperties.ts, 9, 14))
|
||||||
|
|
||||||
|
anotherField: string;
|
||||||
|
>anotherField : Symbol(To.anotherField, Decl(intersectionsAndOptionalProperties.ts, 10, 19))
|
||||||
|
}
|
||||||
|
|
||||||
|
type From = { field: null } & Omit<To, 'field'>;
|
||||||
|
>From : Symbol(From, Decl(intersectionsAndOptionalProperties.ts, 12, 1))
|
||||||
|
>field : Symbol(field, Decl(intersectionsAndOptionalProperties.ts, 14, 14))
|
||||||
|
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
|
||||||
|
>To : Symbol(To, Decl(intersectionsAndOptionalProperties.ts, 5, 6))
|
||||||
|
|
||||||
|
function foo(v: From) {
|
||||||
|
>foo : Symbol(foo, Decl(intersectionsAndOptionalProperties.ts, 14, 49))
|
||||||
|
>v : Symbol(v, Decl(intersectionsAndOptionalProperties.ts, 16, 13))
|
||||||
|
>From : Symbol(From, Decl(intersectionsAndOptionalProperties.ts, 12, 1))
|
||||||
|
|
||||||
|
let x: To;
|
||||||
|
>x : Symbol(x, Decl(intersectionsAndOptionalProperties.ts, 17, 7))
|
||||||
|
>To : Symbol(To, Decl(intersectionsAndOptionalProperties.ts, 5, 6))
|
||||||
|
|
||||||
|
x = v; // Error
|
||||||
|
>x : Symbol(x, Decl(intersectionsAndOptionalProperties.ts, 17, 7))
|
||||||
|
>v : Symbol(v, Decl(intersectionsAndOptionalProperties.ts, 16, 13))
|
||||||
|
|
||||||
|
x.field = v.field; // Error
|
||||||
|
>x.field : Symbol(To.field, Decl(intersectionsAndOptionalProperties.ts, 9, 14))
|
||||||
|
>x : Symbol(x, Decl(intersectionsAndOptionalProperties.ts, 17, 7))
|
||||||
|
>field : Symbol(To.field, Decl(intersectionsAndOptionalProperties.ts, 9, 14))
|
||||||
|
>v.field : Symbol(field, Decl(intersectionsAndOptionalProperties.ts, 14, 14))
|
||||||
|
>v : Symbol(v, Decl(intersectionsAndOptionalProperties.ts, 16, 13))
|
||||||
|
>field : Symbol(field, Decl(intersectionsAndOptionalProperties.ts, 14, 14))
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
=== tests/cases/compiler/intersectionsAndOptionalProperties.ts ===
|
||||||
|
declare let x: { a?: number, b: string };
|
||||||
|
>x : { a?: number | undefined; b: string; }
|
||||||
|
>a : number | undefined
|
||||||
|
>b : string
|
||||||
|
|
||||||
|
declare let y: { a: null, b: string };
|
||||||
|
>y : { a: null; b: string; }
|
||||||
|
>a : null
|
||||||
|
>null : null
|
||||||
|
>b : string
|
||||||
|
|
||||||
|
declare let z: { a: null } & { b: string };
|
||||||
|
>z : { a: null; } & { b: string; }
|
||||||
|
>a : null
|
||||||
|
>null : null
|
||||||
|
>b : string
|
||||||
|
|
||||||
|
x = y; // Error
|
||||||
|
>x = y : { a: null; b: string; }
|
||||||
|
>x : { a?: number | undefined; b: string; }
|
||||||
|
>y : { a: null; b: string; }
|
||||||
|
|
||||||
|
x = z; // Error
|
||||||
|
>x = z : { a: null; } & { b: string; }
|
||||||
|
>x : { a?: number | undefined; b: string; }
|
||||||
|
>z : { a: null; } & { b: string; }
|
||||||
|
|
||||||
|
// Repro from #36604
|
||||||
|
|
||||||
|
interface To {
|
||||||
|
field?: number;
|
||||||
|
>field : number | undefined
|
||||||
|
|
||||||
|
anotherField: string;
|
||||||
|
>anotherField : string
|
||||||
|
}
|
||||||
|
|
||||||
|
type From = { field: null } & Omit<To, 'field'>;
|
||||||
|
>From : From
|
||||||
|
>field : null
|
||||||
|
>null : null
|
||||||
|
|
||||||
|
function foo(v: From) {
|
||||||
|
>foo : (v: From) => void
|
||||||
|
>v : From
|
||||||
|
|
||||||
|
let x: To;
|
||||||
|
>x : To
|
||||||
|
|
||||||
|
x = v; // Error
|
||||||
|
>x = v : From
|
||||||
|
>x : To
|
||||||
|
>v : From
|
||||||
|
|
||||||
|
x.field = v.field; // Error
|
||||||
|
>x.field = v.field : null
|
||||||
|
>x.field : number | undefined
|
||||||
|
>x : To
|
||||||
|
>field : number | undefined
|
||||||
|
>v.field : null
|
||||||
|
>v : From
|
||||||
|
>field : null
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
tests/cases/compiler/normalizedIntersectionTooComplex.ts(36,14): error TS2590: Expression produces a union type that is too complex to represent.
|
||||||
tests/cases/compiler/normalizedIntersectionTooComplex.ts(36,40): error TS7006: Parameter 'x' implicitly has an 'any' type.
|
tests/cases/compiler/normalizedIntersectionTooComplex.ts(36,40): error TS7006: Parameter 'x' implicitly has an 'any' type.
|
||||||
tests/cases/compiler/normalizedIntersectionTooComplex.ts(36,40): error TS2590: Expression produces a union type that is too complex to represent.
|
|
||||||
|
|
||||||
|
|
||||||
==== tests/cases/compiler/normalizedIntersectionTooComplex.ts (2 errors) ====
|
==== tests/cases/compiler/normalizedIntersectionTooComplex.ts (2 errors) ====
|
||||||
|
@ -39,8 +39,8 @@ tests/cases/compiler/normalizedIntersectionTooComplex.ts(36,40): error TS2590: E
|
||||||
declare var all: keyof Big;
|
declare var all: keyof Big;
|
||||||
const ctor = getCtor(all);
|
const ctor = getCtor(all);
|
||||||
const comp = ctor({ common: "ok", ref: x => console.log(x) });
|
const comp = ctor({ common: "ok", ref: x => console.log(x) });
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
!!! error TS2590: Expression produces a union type that is too complex to represent.
|
||||||
~
|
~
|
||||||
!!! error TS7006: Parameter 'x' implicitly has an 'any' type.
|
!!! error TS7006: Parameter 'x' implicitly has an 'any' type.
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
!!! error TS2590: Expression produces a union type that is too complex to represent.
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ export interface Validator<T> {
|
||||||
[nominalTypeHack]?: T;
|
[nominalTypeHack]?: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Requireable<T> extends Validator<T | undefined | null> {
|
export interface Requireable<T> extends Validator<T> {
|
||||||
isRequired: Validator<NonNullable<T>>;
|
isRequired: Validator<NonNullable<T>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,14 +59,14 @@ export interface Validator<T> {
|
||||||
>T : Symbol(T, Decl(index.d.ts, 8, 27))
|
>T : Symbol(T, Decl(index.d.ts, 8, 27))
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Requireable<T> extends Validator<T | undefined | null> {
|
export interface Requireable<T> extends Validator<T> {
|
||||||
>Requireable : Symbol(Requireable, Decl(index.d.ts, 11, 1))
|
>Requireable : Symbol(Requireable, Decl(index.d.ts, 11, 1))
|
||||||
>T : Symbol(T, Decl(index.d.ts, 13, 29))
|
>T : Symbol(T, Decl(index.d.ts, 13, 29))
|
||||||
>Validator : Symbol(Validator, Decl(index.d.ts, 6, 72))
|
>Validator : Symbol(Validator, Decl(index.d.ts, 6, 72))
|
||||||
>T : Symbol(T, Decl(index.d.ts, 13, 29))
|
>T : Symbol(T, Decl(index.d.ts, 13, 29))
|
||||||
|
|
||||||
isRequired: Validator<NonNullable<T>>;
|
isRequired: Validator<NonNullable<T>>;
|
||||||
>isRequired : Symbol(Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>isRequired : Symbol(Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
>Validator : Symbol(Validator, Decl(index.d.ts, 6, 72))
|
>Validator : Symbol(Validator, Decl(index.d.ts, 6, 72))
|
||||||
>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --))
|
>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --))
|
||||||
>T : Symbol(T, Decl(index.d.ts, 13, 29))
|
>T : Symbol(T, Decl(index.d.ts, 13, 29))
|
||||||
|
@ -202,11 +202,11 @@ const innerProps = {
|
||||||
|
|
||||||
foo: PropTypes.string.isRequired,
|
foo: PropTypes.string.isRequired,
|
||||||
>foo : Symbol(foo, Decl(file.ts, 18, 20))
|
>foo : Symbol(foo, Decl(file.ts, 18, 20))
|
||||||
>PropTypes.string.isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>PropTypes.string.isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
>PropTypes.string : Symbol(PropTypes.string, Decl(index.d.ts, 27, 12))
|
>PropTypes.string : Symbol(PropTypes.string, Decl(index.d.ts, 27, 12))
|
||||||
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||||
>string : Symbol(PropTypes.string, Decl(index.d.ts, 27, 12))
|
>string : Symbol(PropTypes.string, Decl(index.d.ts, 27, 12))
|
||||||
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
|
|
||||||
bar: PropTypes.bool,
|
bar: PropTypes.bool,
|
||||||
>bar : Symbol(bar, Decl(file.ts, 19, 37))
|
>bar : Symbol(bar, Decl(file.ts, 19, 37))
|
||||||
|
@ -242,11 +242,11 @@ const arrayOfTypes = [PropTypes.string, PropTypes.bool, PropTypes.shape({
|
||||||
|
|
||||||
bar: PropTypes.number.isRequired
|
bar: PropTypes.number.isRequired
|
||||||
>bar : Symbol(bar, Decl(file.ts, 25, 26))
|
>bar : Symbol(bar, Decl(file.ts, 25, 26))
|
||||||
>PropTypes.number.isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>PropTypes.number.isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
>PropTypes.number : Symbol(PropTypes.number, Decl(index.d.ts, 28, 12))
|
>PropTypes.number : Symbol(PropTypes.number, Decl(index.d.ts, 28, 12))
|
||||||
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||||
>number : Symbol(PropTypes.number, Decl(index.d.ts, 28, 12))
|
>number : Symbol(PropTypes.number, Decl(index.d.ts, 28, 12))
|
||||||
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
|
|
||||||
})];
|
})];
|
||||||
|
|
||||||
|
@ -263,37 +263,37 @@ const propTypes: PropTypesMap = {
|
||||||
|
|
||||||
array: PropTypes.array.isRequired,
|
array: PropTypes.array.isRequired,
|
||||||
>array : Symbol(array, Decl(file.ts, 31, 23))
|
>array : Symbol(array, Decl(file.ts, 31, 23))
|
||||||
>PropTypes.array.isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>PropTypes.array.isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
>PropTypes.array : Symbol(PropTypes.array, Decl(index.d.ts, 25, 12))
|
>PropTypes.array : Symbol(PropTypes.array, Decl(index.d.ts, 25, 12))
|
||||||
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||||
>array : Symbol(PropTypes.array, Decl(index.d.ts, 25, 12))
|
>array : Symbol(PropTypes.array, Decl(index.d.ts, 25, 12))
|
||||||
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
|
|
||||||
bool: PropTypes.bool.isRequired,
|
bool: PropTypes.bool.isRequired,
|
||||||
>bool : Symbol(bool, Decl(file.ts, 32, 38))
|
>bool : Symbol(bool, Decl(file.ts, 32, 38))
|
||||||
>PropTypes.bool.isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>PropTypes.bool.isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
>PropTypes.bool : Symbol(PropTypes.bool, Decl(index.d.ts, 26, 12))
|
>PropTypes.bool : Symbol(PropTypes.bool, Decl(index.d.ts, 26, 12))
|
||||||
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||||
>bool : Symbol(PropTypes.bool, Decl(index.d.ts, 26, 12))
|
>bool : Symbol(PropTypes.bool, Decl(index.d.ts, 26, 12))
|
||||||
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
|
|
||||||
shape: PropTypes.shape(innerProps).isRequired,
|
shape: PropTypes.shape(innerProps).isRequired,
|
||||||
>shape : Symbol(shape, Decl(file.ts, 33, 36))
|
>shape : Symbol(shape, Decl(file.ts, 33, 36))
|
||||||
>PropTypes.shape(innerProps).isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>PropTypes.shape(innerProps).isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
>PropTypes.shape : Symbol(PropTypes.shape, Decl(index.d.ts, 28, 41))
|
>PropTypes.shape : Symbol(PropTypes.shape, Decl(index.d.ts, 28, 41))
|
||||||
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||||
>shape : Symbol(PropTypes.shape, Decl(index.d.ts, 28, 41))
|
>shape : Symbol(PropTypes.shape, Decl(index.d.ts, 28, 41))
|
||||||
>innerProps : Symbol(innerProps, Decl(file.ts, 18, 5))
|
>innerProps : Symbol(innerProps, Decl(file.ts, 18, 5))
|
||||||
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
|
|
||||||
oneOfType: PropTypes.oneOfType(arrayOfTypes).isRequired,
|
oneOfType: PropTypes.oneOfType(arrayOfTypes).isRequired,
|
||||||
>oneOfType : Symbol(oneOfType, Decl(file.ts, 34, 50))
|
>oneOfType : Symbol(oneOfType, Decl(file.ts, 34, 50))
|
||||||
>PropTypes.oneOfType(arrayOfTypes).isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>PropTypes.oneOfType(arrayOfTypes).isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
>PropTypes.oneOfType : Symbol(PropTypes.oneOfType, Decl(index.d.ts, 29, 89))
|
>PropTypes.oneOfType : Symbol(PropTypes.oneOfType, Decl(index.d.ts, 29, 89))
|
||||||
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||||
>oneOfType : Symbol(PropTypes.oneOfType, Decl(index.d.ts, 29, 89))
|
>oneOfType : Symbol(PropTypes.oneOfType, Decl(index.d.ts, 29, 89))
|
||||||
>arrayOfTypes : Symbol(arrayOfTypes, Decl(file.ts, 24, 5))
|
>arrayOfTypes : Symbol(arrayOfTypes, Decl(file.ts, 24, 5))
|
||||||
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -309,37 +309,37 @@ const propTypesWithoutAnnotation = {
|
||||||
|
|
||||||
array: PropTypes.array.isRequired,
|
array: PropTypes.array.isRequired,
|
||||||
>array : Symbol(array, Decl(file.ts, 40, 23))
|
>array : Symbol(array, Decl(file.ts, 40, 23))
|
||||||
>PropTypes.array.isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>PropTypes.array.isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
>PropTypes.array : Symbol(PropTypes.array, Decl(index.d.ts, 25, 12))
|
>PropTypes.array : Symbol(PropTypes.array, Decl(index.d.ts, 25, 12))
|
||||||
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||||
>array : Symbol(PropTypes.array, Decl(index.d.ts, 25, 12))
|
>array : Symbol(PropTypes.array, Decl(index.d.ts, 25, 12))
|
||||||
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
|
|
||||||
bool: PropTypes.bool.isRequired,
|
bool: PropTypes.bool.isRequired,
|
||||||
>bool : Symbol(bool, Decl(file.ts, 41, 38))
|
>bool : Symbol(bool, Decl(file.ts, 41, 38))
|
||||||
>PropTypes.bool.isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>PropTypes.bool.isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
>PropTypes.bool : Symbol(PropTypes.bool, Decl(index.d.ts, 26, 12))
|
>PropTypes.bool : Symbol(PropTypes.bool, Decl(index.d.ts, 26, 12))
|
||||||
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||||
>bool : Symbol(PropTypes.bool, Decl(index.d.ts, 26, 12))
|
>bool : Symbol(PropTypes.bool, Decl(index.d.ts, 26, 12))
|
||||||
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
|
|
||||||
shape: PropTypes.shape(innerProps).isRequired,
|
shape: PropTypes.shape(innerProps).isRequired,
|
||||||
>shape : Symbol(shape, Decl(file.ts, 42, 36))
|
>shape : Symbol(shape, Decl(file.ts, 42, 36))
|
||||||
>PropTypes.shape(innerProps).isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>PropTypes.shape(innerProps).isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
>PropTypes.shape : Symbol(PropTypes.shape, Decl(index.d.ts, 28, 41))
|
>PropTypes.shape : Symbol(PropTypes.shape, Decl(index.d.ts, 28, 41))
|
||||||
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||||
>shape : Symbol(PropTypes.shape, Decl(index.d.ts, 28, 41))
|
>shape : Symbol(PropTypes.shape, Decl(index.d.ts, 28, 41))
|
||||||
>innerProps : Symbol(innerProps, Decl(file.ts, 18, 5))
|
>innerProps : Symbol(innerProps, Decl(file.ts, 18, 5))
|
||||||
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
|
|
||||||
oneOfType: PropTypes.oneOfType(arrayOfTypes).isRequired,
|
oneOfType: PropTypes.oneOfType(arrayOfTypes).isRequired,
|
||||||
>oneOfType : Symbol(oneOfType, Decl(file.ts, 43, 50))
|
>oneOfType : Symbol(oneOfType, Decl(file.ts, 43, 50))
|
||||||
>PropTypes.oneOfType(arrayOfTypes).isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>PropTypes.oneOfType(arrayOfTypes).isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
>PropTypes.oneOfType : Symbol(PropTypes.oneOfType, Decl(index.d.ts, 29, 89))
|
>PropTypes.oneOfType : Symbol(PropTypes.oneOfType, Decl(index.d.ts, 29, 89))
|
||||||
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
>PropTypes : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||||
>oneOfType : Symbol(PropTypes.oneOfType, Decl(index.d.ts, 29, 89))
|
>oneOfType : Symbol(PropTypes.oneOfType, Decl(index.d.ts, 29, 89))
|
||||||
>arrayOfTypes : Symbol(arrayOfTypes, Decl(file.ts, 24, 5))
|
>arrayOfTypes : Symbol(arrayOfTypes, Decl(file.ts, 24, 5))
|
||||||
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 73))
|
>isRequired : Symbol(PropTypes.Requireable.isRequired, Decl(index.d.ts, 13, 54))
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,9 +35,7 @@ export interface Validator<T> {
|
||||||
>nominalTypeHack : unique symbol
|
>nominalTypeHack : unique symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Requireable<T> extends Validator<T | undefined | null> {
|
export interface Requireable<T> extends Validator<T> {
|
||||||
>null : null
|
|
||||||
|
|
||||||
isRequired: Validator<NonNullable<T>>;
|
isRequired: Validator<NonNullable<T>>;
|
||||||
>isRequired : Validator<NonNullable<T>>
|
>isRequired : Validator<NonNullable<T>>
|
||||||
}
|
}
|
||||||
|
|
23
tests/cases/compiler/intersectionsAndOptionalProperties.ts
Normal file
23
tests/cases/compiler/intersectionsAndOptionalProperties.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// @strict: true
|
||||||
|
|
||||||
|
declare let x: { a?: number, b: string };
|
||||||
|
declare let y: { a: null, b: string };
|
||||||
|
declare let z: { a: null } & { b: string };
|
||||||
|
|
||||||
|
x = y; // Error
|
||||||
|
x = z; // Error
|
||||||
|
|
||||||
|
// Repro from #36604
|
||||||
|
|
||||||
|
interface To {
|
||||||
|
field?: number;
|
||||||
|
anotherField: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type From = { field: null } & Omit<To, 'field'>;
|
||||||
|
|
||||||
|
function foo(v: From) {
|
||||||
|
let x: To;
|
||||||
|
x = v; // Error
|
||||||
|
x.field = v.field; // Error
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ export interface Validator<T> {
|
||||||
[nominalTypeHack]?: T;
|
[nominalTypeHack]?: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Requireable<T> extends Validator<T | undefined | null> {
|
export interface Requireable<T> extends Validator<T> {
|
||||||
isRequired: Validator<NonNullable<T>>;
|
isRequired: Validator<NonNullable<T>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue