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
|
||||
// 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 = 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 TS2590: Expression produces a union type that is too complex to represent.
|
||||
|
||||
|
||||
==== 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;
|
||||
const ctor = getCtor(all);
|
||||
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 TS2590: Expression produces a union type that is too complex to represent.
|
||||
|
|
@ -14,7 +14,7 @@ export interface Validator<T> {
|
|||
[nominalTypeHack]?: T;
|
||||
}
|
||||
|
||||
export interface Requireable<T> extends Validator<T | undefined | null> {
|
||||
export interface Requireable<T> extends Validator<T> {
|
||||
isRequired: Validator<NonNullable<T>>;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,14 +59,14 @@ export interface Validator<T> {
|
|||
>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))
|
||||
>T : Symbol(T, Decl(index.d.ts, 13, 29))
|
||||
>Validator : Symbol(Validator, Decl(index.d.ts, 6, 72))
|
||||
>T : Symbol(T, Decl(index.d.ts, 13, 29))
|
||||
|
||||
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))
|
||||
>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(index.d.ts, 13, 29))
|
||||
|
@ -202,11 +202,11 @@ const innerProps = {
|
|||
|
||||
foo: PropTypes.string.isRequired,
|
||||
>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 : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||
>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 : Symbol(bar, Decl(file.ts, 19, 37))
|
||||
|
@ -242,11 +242,11 @@ const arrayOfTypes = [PropTypes.string, PropTypes.bool, PropTypes.shape({
|
|||
|
||||
bar: PropTypes.number.isRequired
|
||||
>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 : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||
>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 : 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 : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||
>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 : 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 : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||
>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 : 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 : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||
>shape : Symbol(PropTypes.shape, Decl(index.d.ts, 28, 41))
|
||||
>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 : 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 : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||
>oneOfType : Symbol(PropTypes.oneOfType, Decl(index.d.ts, 29, 89))
|
||||
>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 : 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 : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||
>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 : 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 : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||
>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 : 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 : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||
>shape : Symbol(PropTypes.shape, Decl(index.d.ts, 28, 41))
|
||||
>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 : 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 : Symbol(PropTypes, Decl(file.ts, 0, 6))
|
||||
>oneOfType : Symbol(PropTypes.oneOfType, Decl(index.d.ts, 29, 89))
|
||||
>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
|
||||
}
|
||||
|
||||
export interface Requireable<T> extends Validator<T | undefined | null> {
|
||||
>null : null
|
||||
|
||||
export interface Requireable<T> extends Validator<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;
|
||||
}
|
||||
|
||||
export interface Requireable<T> extends Validator<T | undefined | null> {
|
||||
export interface Requireable<T> extends Validator<T> {
|
||||
isRequired: Validator<NonNullable<T>>;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue