Print inferred mapped property types as any not {}

This makes them compatible in d.ts and slightly less misleading in
services.
This commit is contained in:
Nathan Shively-Sanders 2018-01-04 12:34:01 -08:00
parent cc7710c71c
commit 5e7ce21a9e
9 changed files with 122 additions and 122 deletions

View file

@ -2862,7 +2862,7 @@ namespace ts {
}
if (resolvedType.stringIndexInfo) {
const indexInfo = resolvedType.objectFlags & ObjectFlags.Deferred ?
createIndexInfo(emptyObjectType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration) :
createIndexInfo(anyType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration) :
resolvedType.stringIndexInfo;
typeElements.push(indexInfoToIndexSignatureDeclarationHelper(indexInfo, IndexKind.String, context));
}
@ -2876,7 +2876,7 @@ namespace ts {
}
for (const propertySymbol of properties) {
const propertyType = getCheckFlags(propertySymbol) & CheckFlags.Deferred ? emptyObjectType : getTypeOfSymbol(propertySymbol);
const propertyType = getCheckFlags(propertySymbol) & CheckFlags.Deferred ? anyType : getTypeOfSymbol(propertySymbol);
const saveEnclosingDeclaration = context.enclosingDeclaration;
context.enclosingDeclaration = undefined;
const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true);
@ -3686,7 +3686,7 @@ namespace ts {
writer.writeLine();
}
const stringIndexInfo = resolved.objectFlags & ObjectFlags.Deferred && resolved.stringIndexInfo ?
createIndexInfo(emptyObjectType, resolved.stringIndexInfo.isReadonly, resolved.stringIndexInfo.declaration) :
createIndexInfo(anyType, resolved.stringIndexInfo.isReadonly, resolved.stringIndexInfo.declaration) :
resolved.stringIndexInfo;
buildIndexSignatureDisplay(stringIndexInfo, writer, IndexKind.String, enclosingDeclaration, globalFlags, symbolStack);
buildIndexSignatureDisplay(resolved.numberIndexInfo, writer, IndexKind.Number, enclosingDeclaration, globalFlags, symbolStack);
@ -3699,7 +3699,7 @@ namespace ts {
writer.reportPrivateInBaseOfClassExpression(symbolName(p));
}
}
const t = getCheckFlags(p) & CheckFlags.Deferred ? emptyObjectType : getTypeOfSymbol(p);
const t = getCheckFlags(p) & CheckFlags.Deferred ? anyType : getTypeOfSymbol(p);
if (p.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(t).length) {
const signatures = getSignaturesOfType(t, SignatureKind.Call);
for (const signature of signatures) {

View file

@ -310,11 +310,11 @@ declare type Spec<T> = {
*/
declare function applySpec<T>(obj: Spec<T>): (...args: any[]) => T;
declare var g1: (...args: any[]) => {
sum: {};
nested: {};
sum: any;
nested: any;
};
declare var g2: (...args: any[]) => {
foo: {};
foo: any;
};
declare const foo: <T>(object: T, partial: Partial<T>) => T;
declare let o: {

View file

@ -203,15 +203,15 @@ function f2() {
};
let v = unboxify(b);
>v : { a: {}; b: {}; c: {}; }
>unboxify(b) : { a: {}; b: {}; c: {}; }
>v : { a: any; b: any; c: any; }
>unboxify(b) : { a: any; b: any; c: any; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
let x: number = v.a;
>x : number
>v.a : number
>v : { a: {}; b: {}; c: {}; }
>v : { a: any; b: any; c: any; }
>a : number
}
@ -277,11 +277,11 @@ function f4() {
};
b = boxify(unboxify(b));
>b = boxify(unboxify(b)) : Boxified<{ a: {}; b: {}; c: {}; }>
>b = boxify(unboxify(b)) : Boxified<{ a: any; b: any; c: any; }>
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>boxify(unboxify(b)) : Boxified<{ a: {}; b: {}; c: {}; }>
>boxify(unboxify(b)) : Boxified<{ a: any; b: any; c: any; }>
>boxify : <T>(obj: T) => Boxified<T>
>unboxify(b) : { a: {}; b: {}; c: {}; }
>unboxify(b) : { a: any; b: any; c: any; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
@ -338,15 +338,15 @@ function f5(s: string) {
});
let v = unboxify(b);
>v : { a: {}; b: {}; c: {}; }
>unboxify(b) : { a: {}; b: {}; c: {}; }
>v : { a: any; b: any; c: any; }
>unboxify(b) : { a: any; b: any; c: any; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { a: Box<number> | Box<string> | Box<boolean>; b: Box<number> | Box<string> | Box<boolean>; c: Box<number> | Box<string> | Box<boolean>; }
let x: string | number | boolean = v.a;
>x : string | number | boolean
>v.a : string | number | boolean
>v : { a: {}; b: {}; c: {}; }
>v : { a: any; b: any; c: any; }
>a : string | number | boolean
}
@ -391,15 +391,15 @@ function f6(s: string) {
});
let v = unboxify(b);
>v : { [x: string]: {}; }
>unboxify(b) : { [x: string]: {}; }
>v : { [x: string]: any; }
>unboxify(b) : { [x: string]: any; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { [x: string]: Box<number> | Box<string> | Box<boolean>; }
let x: string | number | boolean = v[s];
>x : string | number | boolean
>v[s] : string | number | boolean
>v : { [x: string]: {}; }
>v : { [x: string]: any; }
>s : string
}
@ -449,20 +449,20 @@ function f10(foo: Foo) {
>Foo : Foo
let x = validate(foo); // { a: number, readonly b: string }
>x : { a: {}; readonly b: {}; }
>validate(foo) : { a: {}; readonly b: {}; }
>x : { a: any; readonly b: any; }
>validate(foo) : { a: any; readonly b: any; }
>validate : <T>(obj: { [P in keyof T]?: T[P] | undefined; }) => T
>foo : Foo
let y = clone(foo); // { a?: number, b: string }
>y : { a?: {}; b: {}; }
>clone(foo) : { a?: {}; b: {}; }
>y : { a?: any; b: any; }
>clone(foo) : { a?: any; b: any; }
>clone : <T>(obj: { readonly [P in keyof T]: T[P]; }) => T
>foo : Foo
let z = validateAndClone(foo); // { a: number, b: string }
>z : { a: {}; b: {}; }
>validateAndClone(foo) : { a: {}; b: {}; }
>z : { a: any; b: any; }
>validateAndClone(foo) : { a: any; b: any; }
>validateAndClone : <T>(obj: { readonly [P in keyof T]?: T[P] | undefined; }) => T
>foo : Foo
}
@ -507,8 +507,8 @@ declare function applySpec<T>(obj: Spec<T>): (...args: any[]) => T;
// Infers g1: (...args: any[]) => { sum: number, nested: { mul: string } }
var g1 = applySpec({
>g1 : (...args: any[]) => { sum: {}; nested: {}; }
>applySpec({ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }}) : (...args: any[]) => { sum: {}; nested: {}; }
>g1 : (...args: any[]) => { sum: any; nested: any; }
>applySpec({ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }}) : (...args: any[]) => { sum: any; nested: any; }
>applySpec : <T>(obj: Spec<T>) => (...args: any[]) => T
>{ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }} : { sum: (a: any) => number; nested: { mul: (b: any) => string; }; }
@ -532,8 +532,8 @@ var g1 = applySpec({
// Infers g2: (...args: any[]) => { foo: { bar: { baz: boolean } } }
var g2 = applySpec({ foo: { bar: { baz: (x: any) => true } } });
>g2 : (...args: any[]) => { foo: {}; }
>applySpec({ foo: { bar: { baz: (x: any) => true } } }) : (...args: any[]) => { foo: {}; }
>g2 : (...args: any[]) => { foo: any; }
>applySpec({ foo: { bar: { baz: (x: any) => true } } }) : (...args: any[]) => { foo: any; }
>applySpec : <T>(obj: Spec<T>) => (...args: any[]) => T
>{ foo: { bar: { baz: (x: any) => true } } } : { foo: { bar: { baz: (x: any) => boolean; }; }; }
>foo : { bar: { baz: (x: any) => boolean; }; }

View file

@ -1102,10 +1102,10 @@ declare type Handlers<T> = {
};
declare function on<T>(handlerHash: Handlers<T>): T;
declare var hashOfEmpty1: {
test: {};
test: any;
};
declare var hashOfEmpty2: {
test: {};
test: any;
};
interface Options1<Data, Computed> {
data?: Data;

View file

@ -1793,16 +1793,16 @@ declare function on<T>(handlerHash: Handlers<T>): T
>T : T
var hashOfEmpty1 = on({ test: () => {} }); // {}
>hashOfEmpty1 : { test: {}; }
>on({ test: () => {} }) : { test: {}; }
>hashOfEmpty1 : { test: any; }
>on({ test: () => {} }) : { test: any; }
>on : <T>(handlerHash: Handlers<T>) => T
>{ test: () => {} } : { test: () => void; }
>test : () => void
>() => {} : () => void
var hashOfEmpty2 = on({ test: (x: boolean) => {} }); // { test: boolean }
>hashOfEmpty2 : { test: {}; }
>on({ test: (x: boolean) => {} }) : { test: {}; }
>hashOfEmpty2 : { test: any; }
>on({ test: (x: boolean) => {} }) : { test: any; }
>on : <T>(handlerHash: Handlers<T>) => T
>{ test: (x: boolean) => {} } : { test: (x: boolean) => void; }
>test : (x: boolean) => void

View file

@ -1,7 +1,7 @@
tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: {}; baz: {}; }>; } & ThisType<{ x: number; y: number; } & { bar: {}; baz: {}; }>'.
Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: {}; baz: {}; }>; }'.
tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; } & ThisType<{ x: number; y: number; } & { bar: any; baz: any; }>'.
Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; }'.
Types of property 'computed' are incompatible.
Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: {}; baz: {}; }>'.
Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: any; baz: any; }>'.
Types of property 'baz' are incompatible.
Type 'number' is not assignable to type '() => {}'.
@ -35,10 +35,10 @@ tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS
~~~~~
});
~
!!! error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: {}; baz: {}; }>; } & ThisType<{ x: number; y: number; } & { bar: {}; baz: {}; }>'.
!!! error TS2345: Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: {}; baz: {}; }>; }'.
!!! error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; } & ThisType<{ x: number; y: number; } & { bar: any; baz: any; }>'.
!!! error TS2345: Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; }'.
!!! error TS2345: Types of property 'computed' are incompatible.
!!! error TS2345: Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: {}; baz: {}; }>'.
!!! error TS2345: Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: any; baz: any; }>'.
!!! error TS2345: Types of property 'baz' are incompatible.
!!! error TS2345: Type 'number' is not assignable to type '() => {}'.

File diff suppressed because one or more lines are too long

View file

@ -462,8 +462,8 @@ declare function defineProps<T, U>(obj: T, descs: PropDescMap<U> & ThisType<T>):
declare let p10: Point & Record<"foo", number>;
declare let p11: Point & Record<"bar", number>;
declare let p12: Point & {
foo: {};
bar: {};
foo: any;
bar: any;
};
declare type Accessors<T> = {
[K in keyof T]: (() => T[K]) | Computed<T[K]>;
@ -487,6 +487,6 @@ declare let vue: {
} & {
f(x: string): number;
} & {
test: {};
hello: {};
test: any;
hello: any;
};

View file

@ -672,8 +672,8 @@ p11.bar = p11.bar + 1;
>1 : 1
let p12 = defineProps(p1, {
>p12 : Point & { foo: {}; bar: {}; }
>defineProps(p1, { foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }}) : Point & { foo: {}; bar: {}; }
>p12 : Point & { foo: any; bar: any; }
>defineProps(p1, { foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }}) : Point & { foo: any; bar: any; }
>defineProps : <T, U>(obj: T, descs: PropDescMap<U> & ThisType<T>) => T & U
>p1 : Point
>{ foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }} : { foo: { value: number; }; bar: { get(): number; set(value: number): void; }; }
@ -716,22 +716,22 @@ let p12 = defineProps(p1, {
p12.foo = p12.foo + 1;
>p12.foo = p12.foo + 1 : number
>p12.foo : number
>p12 : Point & { foo: {}; bar: {}; }
>p12 : Point & { foo: any; bar: any; }
>foo : number
>p12.foo + 1 : number
>p12.foo : number
>p12 : Point & { foo: {}; bar: {}; }
>p12 : Point & { foo: any; bar: any; }
>foo : number
>1 : 1
p12.bar = p12.bar + 1;
>p12.bar = p12.bar + 1 : number
>p12.bar : number
>p12 : Point & { foo: {}; bar: {}; }
>p12 : Point & { foo: any; bar: any; }
>bar : number
>p12.bar + 1 : number
>p12.bar : number
>p12 : Point & { foo: {}; bar: {}; }
>p12 : Point & { foo: any; bar: any; }
>bar : number
>1 : 1
@ -808,8 +808,8 @@ declare const Vue: new <D, M, P>(options: VueOptions<D, M, P>) => D & M & P;
>P : P
let vue = new Vue({
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; }
>new Vue({ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }}) : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; }
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>new Vue({ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }}) : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>Vue : new <D, M, P>(options: VueOptions<D, M, P>) => D & M & P
>{ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }} : { data: () => { x: number; y: number; }; methods: { f(x: string): number; }; computed: { test(): number; hello: { get(): string; set(value: string): void; }; }; }
@ -833,7 +833,7 @@ let vue = new Vue({
return this.x;
>this.x : number
>this : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; }
>this : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>x : number
}
},
@ -846,7 +846,7 @@ let vue = new Vue({
return this.x;
>this.x : number
>this : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; }
>this : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>x : number
},
@ -870,27 +870,27 @@ let vue = new Vue({
});
vue;
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; }
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
vue.x;
>vue.x : number
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; }
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>x : number
vue.f("abc");
>vue.f("abc") : number
>vue.f : (x: string) => number
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; }
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>f : (x: string) => number
>"abc" : "abc"
vue.test;
>vue.test : number
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; }
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>test : number
vue.hello;
>vue.hello : string
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: {}; hello: {}; }
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>hello : string