Merge pull request #12990 from Microsoft/mappedTypeStringIndexAny
Make mapped types assignable to objects with 'any' string index signature
This commit is contained in:
commit
c05b73328c
|
@ -7730,8 +7730,11 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (relation !== identityRelation && isEmptyObjectType(resolveStructuredTypeMembers(<ObjectType>target))) {
|
||||
return Ternary.True;
|
||||
else if (relation !== identityRelation) {
|
||||
const resolved = resolveStructuredTypeMembers(<ObjectType>target);
|
||||
if (isEmptyObjectType(resolved) || resolved.stringIndexInfo && resolved.stringIndexInfo.type.flags & TypeFlags.Any) {
|
||||
return Ternary.True;
|
||||
}
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
|
|
72
tests/baselines/reference/mappedTypesAndObjects.js
Normal file
72
tests/baselines/reference/mappedTypesAndObjects.js
Normal file
|
@ -0,0 +1,72 @@
|
|||
//// [mappedTypesAndObjects.ts]
|
||||
|
||||
function f1<T>(x: Partial<T>, y: Readonly<T>) {
|
||||
let obj: {};
|
||||
obj = x;
|
||||
obj = y;
|
||||
}
|
||||
|
||||
function f2<T>(x: Partial<T>, y: Readonly<T>) {
|
||||
let obj: { [x: string]: any };
|
||||
obj = x;
|
||||
obj = y;
|
||||
}
|
||||
|
||||
// Repro from #12900
|
||||
|
||||
interface Base {
|
||||
foo: { [key: string]: any };
|
||||
bar: any;
|
||||
baz: any;
|
||||
}
|
||||
|
||||
interface E1<T> extends Base {
|
||||
foo: T;
|
||||
}
|
||||
|
||||
interface Something { name: string, value: string };
|
||||
interface E2 extends Base {
|
||||
foo: Partial<Something>; // or other mapped type
|
||||
}
|
||||
|
||||
interface E3<T> extends Base {
|
||||
foo: Partial<T>; // or other mapped type
|
||||
}
|
||||
|
||||
//// [mappedTypesAndObjects.js]
|
||||
function f1(x, y) {
|
||||
var obj;
|
||||
obj = x;
|
||||
obj = y;
|
||||
}
|
||||
function f2(x, y) {
|
||||
var obj;
|
||||
obj = x;
|
||||
obj = y;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
//// [mappedTypesAndObjects.d.ts]
|
||||
declare function f1<T>(x: Partial<T>, y: Readonly<T>): void;
|
||||
declare function f2<T>(x: Partial<T>, y: Readonly<T>): void;
|
||||
interface Base {
|
||||
foo: {
|
||||
[key: string]: any;
|
||||
};
|
||||
bar: any;
|
||||
baz: any;
|
||||
}
|
||||
interface E1<T> extends Base {
|
||||
foo: T;
|
||||
}
|
||||
interface Something {
|
||||
name: string;
|
||||
value: string;
|
||||
}
|
||||
interface E2 extends Base {
|
||||
foo: Partial<Something>;
|
||||
}
|
||||
interface E3<T> extends Base {
|
||||
foo: Partial<T>;
|
||||
}
|
98
tests/baselines/reference/mappedTypesAndObjects.symbols
Normal file
98
tests/baselines/reference/mappedTypesAndObjects.symbols
Normal file
|
@ -0,0 +1,98 @@
|
|||
=== tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts ===
|
||||
|
||||
function f1<T>(x: Partial<T>, y: Readonly<T>) {
|
||||
>f1 : Symbol(f1, Decl(mappedTypesAndObjects.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 1, 12))
|
||||
>x : Symbol(x, Decl(mappedTypesAndObjects.ts, 1, 15))
|
||||
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 1, 12))
|
||||
>y : Symbol(y, Decl(mappedTypesAndObjects.ts, 1, 29))
|
||||
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 1, 12))
|
||||
|
||||
let obj: {};
|
||||
>obj : Symbol(obj, Decl(mappedTypesAndObjects.ts, 2, 7))
|
||||
|
||||
obj = x;
|
||||
>obj : Symbol(obj, Decl(mappedTypesAndObjects.ts, 2, 7))
|
||||
>x : Symbol(x, Decl(mappedTypesAndObjects.ts, 1, 15))
|
||||
|
||||
obj = y;
|
||||
>obj : Symbol(obj, Decl(mappedTypesAndObjects.ts, 2, 7))
|
||||
>y : Symbol(y, Decl(mappedTypesAndObjects.ts, 1, 29))
|
||||
}
|
||||
|
||||
function f2<T>(x: Partial<T>, y: Readonly<T>) {
|
||||
>f2 : Symbol(f2, Decl(mappedTypesAndObjects.ts, 5, 1))
|
||||
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 7, 12))
|
||||
>x : Symbol(x, Decl(mappedTypesAndObjects.ts, 7, 15))
|
||||
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 7, 12))
|
||||
>y : Symbol(y, Decl(mappedTypesAndObjects.ts, 7, 29))
|
||||
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 7, 12))
|
||||
|
||||
let obj: { [x: string]: any };
|
||||
>obj : Symbol(obj, Decl(mappedTypesAndObjects.ts, 8, 7))
|
||||
>x : Symbol(x, Decl(mappedTypesAndObjects.ts, 8, 16))
|
||||
|
||||
obj = x;
|
||||
>obj : Symbol(obj, Decl(mappedTypesAndObjects.ts, 8, 7))
|
||||
>x : Symbol(x, Decl(mappedTypesAndObjects.ts, 7, 15))
|
||||
|
||||
obj = y;
|
||||
>obj : Symbol(obj, Decl(mappedTypesAndObjects.ts, 8, 7))
|
||||
>y : Symbol(y, Decl(mappedTypesAndObjects.ts, 7, 29))
|
||||
}
|
||||
|
||||
// Repro from #12900
|
||||
|
||||
interface Base {
|
||||
>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1))
|
||||
|
||||
foo: { [key: string]: any };
|
||||
>foo : Symbol(Base.foo, Decl(mappedTypesAndObjects.ts, 15, 16))
|
||||
>key : Symbol(key, Decl(mappedTypesAndObjects.ts, 16, 11))
|
||||
|
||||
bar: any;
|
||||
>bar : Symbol(Base.bar, Decl(mappedTypesAndObjects.ts, 16, 31))
|
||||
|
||||
baz: any;
|
||||
>baz : Symbol(Base.baz, Decl(mappedTypesAndObjects.ts, 17, 12))
|
||||
}
|
||||
|
||||
interface E1<T> extends Base {
|
||||
>E1 : Symbol(E1, Decl(mappedTypesAndObjects.ts, 19, 1))
|
||||
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 21, 13))
|
||||
>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1))
|
||||
|
||||
foo: T;
|
||||
>foo : Symbol(E1.foo, Decl(mappedTypesAndObjects.ts, 21, 30))
|
||||
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 21, 13))
|
||||
}
|
||||
|
||||
interface Something { name: string, value: string };
|
||||
>Something : Symbol(Something, Decl(mappedTypesAndObjects.ts, 23, 1))
|
||||
>name : Symbol(Something.name, Decl(mappedTypesAndObjects.ts, 25, 21))
|
||||
>value : Symbol(Something.value, Decl(mappedTypesAndObjects.ts, 25, 35))
|
||||
|
||||
interface E2 extends Base {
|
||||
>E2 : Symbol(E2, Decl(mappedTypesAndObjects.ts, 25, 52))
|
||||
>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1))
|
||||
|
||||
foo: Partial<Something>; // or other mapped type
|
||||
>foo : Symbol(E2.foo, Decl(mappedTypesAndObjects.ts, 26, 27))
|
||||
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
|
||||
>Something : Symbol(Something, Decl(mappedTypesAndObjects.ts, 23, 1))
|
||||
}
|
||||
|
||||
interface E3<T> extends Base {
|
||||
>E3 : Symbol(E3, Decl(mappedTypesAndObjects.ts, 28, 1))
|
||||
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 30, 13))
|
||||
>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1))
|
||||
|
||||
foo: Partial<T>; // or other mapped type
|
||||
>foo : Symbol(E3.foo, Decl(mappedTypesAndObjects.ts, 30, 30))
|
||||
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 30, 13))
|
||||
}
|
102
tests/baselines/reference/mappedTypesAndObjects.types
Normal file
102
tests/baselines/reference/mappedTypesAndObjects.types
Normal file
|
@ -0,0 +1,102 @@
|
|||
=== tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts ===
|
||||
|
||||
function f1<T>(x: Partial<T>, y: Readonly<T>) {
|
||||
>f1 : <T>(x: Partial<T>, y: Readonly<T>) => void
|
||||
>T : T
|
||||
>x : Partial<T>
|
||||
>Partial : Partial<T>
|
||||
>T : T
|
||||
>y : Readonly<T>
|
||||
>Readonly : Readonly<T>
|
||||
>T : T
|
||||
|
||||
let obj: {};
|
||||
>obj : {}
|
||||
|
||||
obj = x;
|
||||
>obj = x : Partial<T>
|
||||
>obj : {}
|
||||
>x : Partial<T>
|
||||
|
||||
obj = y;
|
||||
>obj = y : Readonly<T>
|
||||
>obj : {}
|
||||
>y : Readonly<T>
|
||||
}
|
||||
|
||||
function f2<T>(x: Partial<T>, y: Readonly<T>) {
|
||||
>f2 : <T>(x: Partial<T>, y: Readonly<T>) => void
|
||||
>T : T
|
||||
>x : Partial<T>
|
||||
>Partial : Partial<T>
|
||||
>T : T
|
||||
>y : Readonly<T>
|
||||
>Readonly : Readonly<T>
|
||||
>T : T
|
||||
|
||||
let obj: { [x: string]: any };
|
||||
>obj : { [x: string]: any; }
|
||||
>x : string
|
||||
|
||||
obj = x;
|
||||
>obj = x : Partial<T>
|
||||
>obj : { [x: string]: any; }
|
||||
>x : Partial<T>
|
||||
|
||||
obj = y;
|
||||
>obj = y : Readonly<T>
|
||||
>obj : { [x: string]: any; }
|
||||
>y : Readonly<T>
|
||||
}
|
||||
|
||||
// Repro from #12900
|
||||
|
||||
interface Base {
|
||||
>Base : Base
|
||||
|
||||
foo: { [key: string]: any };
|
||||
>foo : { [key: string]: any; }
|
||||
>key : string
|
||||
|
||||
bar: any;
|
||||
>bar : any
|
||||
|
||||
baz: any;
|
||||
>baz : any
|
||||
}
|
||||
|
||||
interface E1<T> extends Base {
|
||||
>E1 : E1<T>
|
||||
>T : T
|
||||
>Base : Base
|
||||
|
||||
foo: T;
|
||||
>foo : T
|
||||
>T : T
|
||||
}
|
||||
|
||||
interface Something { name: string, value: string };
|
||||
>Something : Something
|
||||
>name : string
|
||||
>value : string
|
||||
|
||||
interface E2 extends Base {
|
||||
>E2 : E2
|
||||
>Base : Base
|
||||
|
||||
foo: Partial<Something>; // or other mapped type
|
||||
>foo : Partial<Something>
|
||||
>Partial : Partial<T>
|
||||
>Something : Something
|
||||
}
|
||||
|
||||
interface E3<T> extends Base {
|
||||
>E3 : E3<T>
|
||||
>T : T
|
||||
>Base : Base
|
||||
|
||||
foo: Partial<T>; // or other mapped type
|
||||
>foo : Partial<T>
|
||||
>Partial : Partial<T>
|
||||
>T : T
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// @strictNullChecks: true
|
||||
// @declaration: true
|
||||
|
||||
function f1<T>(x: Partial<T>, y: Readonly<T>) {
|
||||
let obj: {};
|
||||
obj = x;
|
||||
obj = y;
|
||||
}
|
||||
|
||||
function f2<T>(x: Partial<T>, y: Readonly<T>) {
|
||||
let obj: { [x: string]: any };
|
||||
obj = x;
|
||||
obj = y;
|
||||
}
|
||||
|
||||
// Repro from #12900
|
||||
|
||||
interface Base {
|
||||
foo: { [key: string]: any };
|
||||
bar: any;
|
||||
baz: any;
|
||||
}
|
||||
|
||||
interface E1<T> extends Base {
|
||||
foo: T;
|
||||
}
|
||||
|
||||
interface Something { name: string, value: string };
|
||||
interface E2 extends Base {
|
||||
foo: Partial<Something>; // or other mapped type
|
||||
}
|
||||
|
||||
interface E3<T> extends Base {
|
||||
foo: Partial<T>; // or other mapped type
|
||||
}
|
Loading…
Reference in a new issue