mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 02:33:53 -06:00
Fresh {} is subtype of object (#49503)
* Fresh {} is subtype of object
* Add regression test
This commit is contained in:
parent
2ecde27187
commit
dc6a80bd00
@ -18189,7 +18189,7 @@ namespace ts {
|
||||
// Since unions and intersections may reduce to `never`, we exclude them here.
|
||||
if (s & TypeFlags.Undefined && (!strictNullChecks && !(t & TypeFlags.UnionOrIntersection) || t & (TypeFlags.Undefined | TypeFlags.Void))) return true;
|
||||
if (s & TypeFlags.Null && (!strictNullChecks && !(t & TypeFlags.UnionOrIntersection) || t & TypeFlags.Null)) return true;
|
||||
if (s & TypeFlags.Object && t & TypeFlags.NonPrimitive && !(relation === strictSubtypeRelation && isEmptyAnonymousObjectType(source))) return true;
|
||||
if (s & TypeFlags.Object && t & TypeFlags.NonPrimitive && !(relation === strictSubtypeRelation && isEmptyAnonymousObjectType(source) && !(getObjectFlags(source) & ObjectFlags.FreshLiteral))) return true;
|
||||
if (relation === assignableRelation || relation === comparableRelation) {
|
||||
if (s & TypeFlags.Any) return true;
|
||||
// Type number or any numeric literal type is assignable to any numeric enum type or any
|
||||
@ -18935,7 +18935,7 @@ namespace ts {
|
||||
return typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), target as UnionType, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive));
|
||||
}
|
||||
if (target.flags & TypeFlags.Intersection) {
|
||||
return typeRelatedToEachType(getRegularTypeOfObjectLiteral(source), target as IntersectionType, reportErrors, IntersectionState.Target);
|
||||
return typeRelatedToEachType(source, target as IntersectionType, reportErrors, IntersectionState.Target);
|
||||
}
|
||||
// Source is an intersection. For the comparable relation, if the target is a primitive type we hoist the
|
||||
// constraints of all non-primitive types in the source into a new intersection. We do this because the
|
||||
|
||||
32
tests/baselines/reference/nonPrimitiveAndEmptyObject.js
Normal file
32
tests/baselines/reference/nonPrimitiveAndEmptyObject.js
Normal file
@ -0,0 +1,32 @@
|
||||
//// [nonPrimitiveAndEmptyObject.ts]
|
||||
// Repro from #49480
|
||||
|
||||
export interface BarProps {
|
||||
barProp?: string;
|
||||
}
|
||||
|
||||
export interface FooProps {
|
||||
fooProps?: BarProps & object;
|
||||
}
|
||||
|
||||
declare const foo: FooProps;
|
||||
const { fooProps = {} } = foo;
|
||||
|
||||
fooProps.barProp;
|
||||
|
||||
|
||||
//// [nonPrimitiveAndEmptyObject.js]
|
||||
"use strict";
|
||||
// Repro from #49480
|
||||
exports.__esModule = true;
|
||||
var _a = foo.fooProps, fooProps = _a === void 0 ? {} : _a;
|
||||
fooProps.barProp;
|
||||
|
||||
|
||||
//// [nonPrimitiveAndEmptyObject.d.ts]
|
||||
export interface BarProps {
|
||||
barProp?: string;
|
||||
}
|
||||
export interface FooProps {
|
||||
fooProps?: BarProps & object;
|
||||
}
|
||||
31
tests/baselines/reference/nonPrimitiveAndEmptyObject.symbols
Normal file
31
tests/baselines/reference/nonPrimitiveAndEmptyObject.symbols
Normal file
@ -0,0 +1,31 @@
|
||||
=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveAndEmptyObject.ts ===
|
||||
// Repro from #49480
|
||||
|
||||
export interface BarProps {
|
||||
>BarProps : Symbol(BarProps, Decl(nonPrimitiveAndEmptyObject.ts, 0, 0))
|
||||
|
||||
barProp?: string;
|
||||
>barProp : Symbol(BarProps.barProp, Decl(nonPrimitiveAndEmptyObject.ts, 2, 27))
|
||||
}
|
||||
|
||||
export interface FooProps {
|
||||
>FooProps : Symbol(FooProps, Decl(nonPrimitiveAndEmptyObject.ts, 4, 1))
|
||||
|
||||
fooProps?: BarProps & object;
|
||||
>fooProps : Symbol(FooProps.fooProps, Decl(nonPrimitiveAndEmptyObject.ts, 6, 27))
|
||||
>BarProps : Symbol(BarProps, Decl(nonPrimitiveAndEmptyObject.ts, 0, 0))
|
||||
}
|
||||
|
||||
declare const foo: FooProps;
|
||||
>foo : Symbol(foo, Decl(nonPrimitiveAndEmptyObject.ts, 10, 13))
|
||||
>FooProps : Symbol(FooProps, Decl(nonPrimitiveAndEmptyObject.ts, 4, 1))
|
||||
|
||||
const { fooProps = {} } = foo;
|
||||
>fooProps : Symbol(fooProps, Decl(nonPrimitiveAndEmptyObject.ts, 11, 7))
|
||||
>foo : Symbol(foo, Decl(nonPrimitiveAndEmptyObject.ts, 10, 13))
|
||||
|
||||
fooProps.barProp;
|
||||
>fooProps.barProp : Symbol(BarProps.barProp, Decl(nonPrimitiveAndEmptyObject.ts, 2, 27))
|
||||
>fooProps : Symbol(fooProps, Decl(nonPrimitiveAndEmptyObject.ts, 11, 7))
|
||||
>barProp : Symbol(BarProps.barProp, Decl(nonPrimitiveAndEmptyObject.ts, 2, 27))
|
||||
|
||||
26
tests/baselines/reference/nonPrimitiveAndEmptyObject.types
Normal file
26
tests/baselines/reference/nonPrimitiveAndEmptyObject.types
Normal file
@ -0,0 +1,26 @@
|
||||
=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveAndEmptyObject.ts ===
|
||||
// Repro from #49480
|
||||
|
||||
export interface BarProps {
|
||||
barProp?: string;
|
||||
>barProp : string | undefined
|
||||
}
|
||||
|
||||
export interface FooProps {
|
||||
fooProps?: BarProps & object;
|
||||
>fooProps : (BarProps & object) | undefined
|
||||
}
|
||||
|
||||
declare const foo: FooProps;
|
||||
>foo : FooProps
|
||||
|
||||
const { fooProps = {} } = foo;
|
||||
>fooProps : BarProps & object
|
||||
>{} : {}
|
||||
>foo : FooProps
|
||||
|
||||
fooProps.barProp;
|
||||
>fooProps.barProp : string | undefined
|
||||
>fooProps : BarProps & object
|
||||
>barProp : string | undefined
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
// Repro from #49480
|
||||
|
||||
export interface BarProps {
|
||||
barProp?: string;
|
||||
}
|
||||
|
||||
export interface FooProps {
|
||||
fooProps?: BarProps & object;
|
||||
}
|
||||
|
||||
declare const foo: FooProps;
|
||||
const { fooProps = {} } = foo;
|
||||
|
||||
fooProps.barProp;
|
||||
Loading…
x
Reference in New Issue
Block a user