Add tests

This commit is contained in:
Anders Hejlsberg 2017-02-27 10:19:26 -08:00
parent cd87d903a0
commit 5bda48ba8d
4 changed files with 1310 additions and 0 deletions

View File

@ -0,0 +1,293 @@
//// [thisTypeInObjectLiterals2.ts]
// In methods of an object literal with no contextual type, 'this' has the type
// of the object literal.
let obj1 = {
a: 1,
f() {
return this.a;
},
b: "hello",
c: {
g() {
this.g();
}
},
get d() {
return this.a;
},
get e() {
return this.b;
},
set e(value) {
this.b = value;
}
};
// In methods of an object literal with a contextual type, 'this' has the
// contextual type.
type Point = {
x: number;
y: number;
moveBy(dx: number, dy: number): void;
}
let p1: Point = {
x: 10,
y: 20,
moveBy(dx, dy) {
this.x += dx;
this.y += dy;
}
};
declare function f1(p: Point): void;
f1({
x: 10,
y: 20,
moveBy(dx, dy) {
this.x += dx;
this.y += dy;
}
});
// In methods of an object literal with a contextual type that includes some
// ThisType<T>, 'this' is of type T.
type ObjectDescriptor<D, M> = {
data?: D;
methods?: M & ThisType<D & M>; // Type of 'this' in methods is D & M
}
declare function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M;
let x1 = makeObject({
data: { x: 0, y: 0 },
methods: {
moveBy(dx: number, dy: number) {
this.x += dx; // Strongly typed this
this.y += dy; // Strongly typed this
}
}
});
// In methods contained in an object literal with a contextual type that includes
// some ThisType<T>, 'this' is of type T.
type ObjectDescriptor2<D, M> = ThisType<D & M> & {
data?: D;
methods?: M;
}
declare function makeObject2<D, M>(desc: ObjectDescriptor<D, M>): D & M;
let x2 = makeObject2({
data: { x: 0, y: 0 },
methods: {
moveBy(dx: number, dy: number) {
this.x += dx; // Strongly typed this
this.y += dy; // Strongly typed this
}
}
});
// Proof of concept for typing of Vue.js
type Accessors<T> = { [K in keyof T]: (() => T[K]) | Computed<T[K]> };
type Dictionary<T> = { [x: string]: T }
type Computed<T> = {
get?(): T;
set?(value: T): void;
}
type VueOptions<D, M, P> = ThisType<D & M & P> & {
data?: D | (() => D);
methods?: M;
computed?: Accessors<P>;
}
declare const Vue: new <D, M, P>(options: VueOptions<D, M, P>) => D & M & P;
let vue = 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) {
}
}
}
});
vue;
vue.x;
vue.f("abc");
vue.test;
vue.hello;
//// [thisTypeInObjectLiterals2.js]
// In methods of an object literal with no contextual type, 'this' has the type
// of the object literal.
var obj1 = {
a: 1,
f: function () {
return this.a;
},
b: "hello",
c: {
g: function () {
this.g();
}
},
get d() {
return this.a;
},
get e() {
return this.b;
},
set e(value) {
this.b = value;
}
};
var p1 = {
x: 10,
y: 20,
moveBy: function (dx, dy) {
this.x += dx;
this.y += dy;
}
};
f1({
x: 10,
y: 20,
moveBy: function (dx, dy) {
this.x += dx;
this.y += dy;
}
});
var x1 = makeObject({
data: { x: 0, y: 0 },
methods: {
moveBy: function (dx, dy) {
this.x += dx; // Strongly typed this
this.y += dy; // Strongly typed this
}
}
});
var x2 = makeObject2({
data: { x: 0, y: 0 },
methods: {
moveBy: function (dx, dy) {
this.x += dx; // Strongly typed this
this.y += dy; // Strongly typed this
}
}
});
var vue = new Vue({
data: function () { return ({ x: 1, y: 2 }); },
methods: {
f: function (x) {
return this.x;
}
},
computed: {
test: function () {
return this.x;
},
hello: {
get: function () {
return "hi";
},
set: function (value) {
}
}
}
});
vue;
vue.x;
vue.f("abc");
vue.test;
vue.hello;
//// [thisTypeInObjectLiterals2.d.ts]
declare let obj1: {
a: number;
f(): number;
b: string;
c: {
g(): void;
};
readonly d: number;
e: string;
};
declare type Point = {
x: number;
y: number;
moveBy(dx: number, dy: number): void;
};
declare let p1: Point;
declare function f1(p: Point): void;
declare type ObjectDescriptor<D, M> = {
data?: D;
methods?: M & ThisType<D & M>;
};
declare function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M;
declare let x1: {
x: number;
y: number;
} & {
moveBy(dx: number, dy: number): void;
};
declare type ObjectDescriptor2<D, M> = ThisType<D & M> & {
data?: D;
methods?: M;
};
declare function makeObject2<D, M>(desc: ObjectDescriptor<D, M>): D & M;
declare let x2: {
x: number;
y: number;
} & {
moveBy(dx: number, dy: number): void;
};
declare type Accessors<T> = {
[K in keyof T]: (() => T[K]) | Computed<T[K]>;
};
declare type Dictionary<T> = {
[x: string]: T;
};
declare type Computed<T> = {
get?(): T;
set?(value: T): void;
};
declare type VueOptions<D, M, P> = ThisType<D & M & P> & {
data?: D | (() => D);
methods?: M;
computed?: Accessors<P>;
};
declare const Vue: new <D, M, P>(options: VueOptions<D, M, P>) => D & M & P;
declare let vue: {
x: number;
y: number;
} & {
f(x: string): number;
} & {
test: number;
hello: string;
};

View File

@ -0,0 +1,410 @@
=== tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts ===
// In methods of an object literal with no contextual type, 'this' has the type
// of the object literal.
let obj1 = {
>obj1 : Symbol(obj1, Decl(thisTypeInObjectLiterals2.ts, 4, 3))
a: 1,
>a : Symbol(a, Decl(thisTypeInObjectLiterals2.ts, 4, 12))
f() {
>f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 5, 9))
return this.a;
>this.a : Symbol(a, Decl(thisTypeInObjectLiterals2.ts, 4, 12))
>this : Symbol(obj1, Decl(thisTypeInObjectLiterals2.ts, 4, 10))
>a : Symbol(a, Decl(thisTypeInObjectLiterals2.ts, 4, 12))
},
b: "hello",
>b : Symbol(b, Decl(thisTypeInObjectLiterals2.ts, 8, 6))
c: {
>c : Symbol(c, Decl(thisTypeInObjectLiterals2.ts, 9, 15))
g() {
>g : Symbol(g, Decl(thisTypeInObjectLiterals2.ts, 10, 8))
this.g();
>this.g : Symbol(g, Decl(thisTypeInObjectLiterals2.ts, 10, 8))
>this : Symbol(__object, Decl(thisTypeInObjectLiterals2.ts, 10, 6))
>g : Symbol(g, Decl(thisTypeInObjectLiterals2.ts, 10, 8))
}
},
get d() {
>d : Symbol(d, Decl(thisTypeInObjectLiterals2.ts, 14, 6))
return this.a;
>this.a : Symbol(a, Decl(thisTypeInObjectLiterals2.ts, 4, 12))
>this : Symbol(obj1, Decl(thisTypeInObjectLiterals2.ts, 4, 10))
>a : Symbol(a, Decl(thisTypeInObjectLiterals2.ts, 4, 12))
},
get e() {
>e : Symbol(e, Decl(thisTypeInObjectLiterals2.ts, 17, 6), Decl(thisTypeInObjectLiterals2.ts, 20, 6))
return this.b;
>this.b : Symbol(b, Decl(thisTypeInObjectLiterals2.ts, 8, 6))
>this : Symbol(obj1, Decl(thisTypeInObjectLiterals2.ts, 4, 10))
>b : Symbol(b, Decl(thisTypeInObjectLiterals2.ts, 8, 6))
},
set e(value) {
>e : Symbol(e, Decl(thisTypeInObjectLiterals2.ts, 17, 6), Decl(thisTypeInObjectLiterals2.ts, 20, 6))
>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 21, 10))
this.b = value;
>this.b : Symbol(b, Decl(thisTypeInObjectLiterals2.ts, 8, 6))
>this : Symbol(obj1, Decl(thisTypeInObjectLiterals2.ts, 4, 10))
>b : Symbol(b, Decl(thisTypeInObjectLiterals2.ts, 8, 6))
>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 21, 10))
}
};
// In methods of an object literal with a contextual type, 'this' has the
// contextual type.
type Point = {
>Point : Symbol(Point, Decl(thisTypeInObjectLiterals2.ts, 24, 2))
x: number;
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14))
y: number;
>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14))
moveBy(dx: number, dy: number): void;
>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 31, 14))
>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 32, 11))
>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 32, 22))
}
let p1: Point = {
>p1 : Symbol(p1, Decl(thisTypeInObjectLiterals2.ts, 35, 3))
>Point : Symbol(Point, Decl(thisTypeInObjectLiterals2.ts, 24, 2))
x: 10,
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 35, 17))
y: 20,
>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 36, 10))
moveBy(dx, dy) {
>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 37, 10))
>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 38, 11))
>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 38, 14))
this.x += dx;
>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14))
>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12))
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14))
>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 38, 11))
this.y += dy;
>this.y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14))
>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12))
>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14))
>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 38, 14))
}
};
declare function f1(p: Point): void;
>f1 : Symbol(f1, Decl(thisTypeInObjectLiterals2.ts, 42, 2))
>p : Symbol(p, Decl(thisTypeInObjectLiterals2.ts, 44, 20))
>Point : Symbol(Point, Decl(thisTypeInObjectLiterals2.ts, 24, 2))
f1({
>f1 : Symbol(f1, Decl(thisTypeInObjectLiterals2.ts, 42, 2))
x: 10,
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 46, 4))
y: 20,
>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 47, 10))
moveBy(dx, dy) {
>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 48, 10))
>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 49, 11))
>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 49, 14))
this.x += dx;
>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14))
>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12))
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 29, 14))
>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 49, 11))
this.y += dy;
>this.y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14))
>this : Symbol(__type, Decl(thisTypeInObjectLiterals2.ts, 29, 12))
>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 30, 14))
>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 49, 14))
}
});
// In methods of an object literal with a contextual type that includes some
// ThisType<T>, 'this' is of type T.
type ObjectDescriptor<D, M> = {
>ObjectDescriptor : Symbol(ObjectDescriptor, Decl(thisTypeInObjectLiterals2.ts, 53, 3))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 58, 22))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 58, 24))
data?: D;
>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 58, 31))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 58, 22))
methods?: M & ThisType<D & M>; // Type of 'this' in methods is D & M
>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 59, 13))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 58, 24))
>ThisType : Symbol(ThisType, Decl(lib.d.ts, --, --))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 58, 22))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 58, 24))
}
declare function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M;
>makeObject : Symbol(makeObject, Decl(thisTypeInObjectLiterals2.ts, 61, 1))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 63, 28))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 63, 30))
>desc : Symbol(desc, Decl(thisTypeInObjectLiterals2.ts, 63, 34))
>ObjectDescriptor : Symbol(ObjectDescriptor, Decl(thisTypeInObjectLiterals2.ts, 53, 3))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 63, 28))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 63, 30))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 63, 28))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 63, 30))
let x1 = makeObject({
>x1 : Symbol(x1, Decl(thisTypeInObjectLiterals2.ts, 65, 3))
>makeObject : Symbol(makeObject, Decl(thisTypeInObjectLiterals2.ts, 61, 1))
data: { x: 0, y: 0 },
>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 65, 21))
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 66, 11))
>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 66, 17))
methods: {
>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 66, 25))
moveBy(dx: number, dy: number) {
>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 67, 14))
>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 68, 15))
>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 68, 26))
this.x += dx; // Strongly typed this
>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 66, 11))
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 66, 11))
>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 68, 15))
this.y += dy; // Strongly typed this
>this.y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 66, 17))
>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 66, 17))
>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 68, 26))
}
}
});
// In methods contained in an object literal with a contextual type that includes
// some ThisType<T>, 'this' is of type T.
type ObjectDescriptor2<D, M> = ThisType<D & M> & {
>ObjectDescriptor2 : Symbol(ObjectDescriptor2, Decl(thisTypeInObjectLiterals2.ts, 73, 3))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 78, 23))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 78, 25))
>ThisType : Symbol(ThisType, Decl(lib.d.ts, --, --))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 78, 23))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 78, 25))
data?: D;
>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 78, 50))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 78, 23))
methods?: M;
>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 79, 13))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 78, 25))
}
declare function makeObject2<D, M>(desc: ObjectDescriptor<D, M>): D & M;
>makeObject2 : Symbol(makeObject2, Decl(thisTypeInObjectLiterals2.ts, 81, 1))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 83, 29))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 83, 31))
>desc : Symbol(desc, Decl(thisTypeInObjectLiterals2.ts, 83, 35))
>ObjectDescriptor : Symbol(ObjectDescriptor, Decl(thisTypeInObjectLiterals2.ts, 53, 3))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 83, 29))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 83, 31))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 83, 29))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 83, 31))
let x2 = makeObject2({
>x2 : Symbol(x2, Decl(thisTypeInObjectLiterals2.ts, 85, 3))
>makeObject2 : Symbol(makeObject2, Decl(thisTypeInObjectLiterals2.ts, 81, 1))
data: { x: 0, y: 0 },
>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 85, 22))
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 86, 11))
>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 86, 17))
methods: {
>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 86, 25))
moveBy(dx: number, dy: number) {
>moveBy : Symbol(moveBy, Decl(thisTypeInObjectLiterals2.ts, 87, 14))
>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 88, 15))
>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 88, 26))
this.x += dx; // Strongly typed this
>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 86, 11))
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 86, 11))
>dx : Symbol(dx, Decl(thisTypeInObjectLiterals2.ts, 88, 15))
this.y += dy; // Strongly typed this
>this.y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 86, 17))
>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 86, 17))
>dy : Symbol(dy, Decl(thisTypeInObjectLiterals2.ts, 88, 26))
}
}
});
// Proof of concept for typing of Vue.js
type Accessors<T> = { [K in keyof T]: (() => T[K]) | Computed<T[K]> };
>Accessors : Symbol(Accessors, Decl(thisTypeInObjectLiterals2.ts, 93, 3))
>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 97, 15))
>K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 97, 23))
>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 97, 15))
>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 97, 15))
>K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 97, 23))
>Computed : Symbol(Computed, Decl(thisTypeInObjectLiterals2.ts, 99, 39))
>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 97, 15))
>K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 97, 23))
type Dictionary<T> = { [x: string]: T }
>Dictionary : Symbol(Dictionary, Decl(thisTypeInObjectLiterals2.ts, 97, 70))
>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 99, 16))
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 99, 24))
>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 99, 16))
type Computed<T> = {
>Computed : Symbol(Computed, Decl(thisTypeInObjectLiterals2.ts, 99, 39))
>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 101, 14))
get?(): T;
>get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 101, 20))
>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 101, 14))
set?(value: T): void;
>set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 102, 14))
>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 103, 9))
>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 101, 14))
}
type VueOptions<D, M, P> = ThisType<D & M & P> & {
>VueOptions : Symbol(VueOptions, Decl(thisTypeInObjectLiterals2.ts, 104, 1))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 106, 16))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 106, 18))
>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 106, 21))
>ThisType : Symbol(ThisType, Decl(lib.d.ts, --, --))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 106, 16))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 106, 18))
>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 106, 21))
data?: D | (() => D);
>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 106, 50))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 106, 16))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 106, 16))
methods?: M;
>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 107, 25))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 106, 18))
computed?: Accessors<P>;
>computed : Symbol(computed, Decl(thisTypeInObjectLiterals2.ts, 108, 16))
>Accessors : Symbol(Accessors, Decl(thisTypeInObjectLiterals2.ts, 93, 3))
>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 106, 21))
}
declare const Vue: new <D, M, P>(options: VueOptions<D, M, P>) => D & M & P;
>Vue : Symbol(Vue, Decl(thisTypeInObjectLiterals2.ts, 112, 13))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 112, 24))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 112, 26))
>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 112, 29))
>options : Symbol(options, Decl(thisTypeInObjectLiterals2.ts, 112, 33))
>VueOptions : Symbol(VueOptions, Decl(thisTypeInObjectLiterals2.ts, 104, 1))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 112, 24))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 112, 26))
>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 112, 29))
>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 112, 24))
>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 112, 26))
>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 112, 29))
let vue = new Vue({
>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3))
>Vue : Symbol(Vue, Decl(thisTypeInObjectLiterals2.ts, 112, 13))
data: () => ({ x: 1, y: 2 }),
>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 114, 19))
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18))
>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 115, 24))
methods: {
>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 115, 33))
f(x: string) {
>f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 116, 14))
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 117, 10))
return this.x;
>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18))
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18))
}
},
computed: {
>computed : Symbol(computed, Decl(thisTypeInObjectLiterals2.ts, 120, 6))
test(): number {
>test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 121, 15))
return this.x;
>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18))
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18))
},
hello: {
>hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 124, 10))
get() {
>get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 125, 16))
return "hi";
},
set(value: string) {
>set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 128, 14))
>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 129, 16))
}
}
}
});
vue;
>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3))
vue.x;
>vue.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18))
>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3))
>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 115, 18))
vue.f("abc");
>vue.f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 116, 14))
>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3))
>f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 116, 14))
vue.test;
>vue.test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 121, 15))
>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3))
>test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 121, 15))
vue.hello;
>vue.hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 124, 10))
>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 114, 3))
>hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 124, 10))

View File

@ -0,0 +1,463 @@
=== tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts ===
// In methods of an object literal with no contextual type, 'this' has the type
// of the object literal.
let obj1 = {
>obj1 : { a: number; f(): number; b: string; c: { g(): void; }; readonly d: number; e: string; }
>{ a: 1, f() { return this.a; }, b: "hello", c: { g() { this.g(); } }, get d() { return this.a; }, get e() { return this.b; }, set e(value) { this.b = value; }} : { a: number; f(): number; b: string; c: { g(): void; }; readonly d: number; e: string; }
a: 1,
>a : number
>1 : 1
f() {
>f : () => number
return this.a;
>this.a : number
>this : { a: number; f(): number; b: string; c: { g(): void; }; readonly d: number; e: string; }
>a : number
},
b: "hello",
>b : string
>"hello" : "hello"
c: {
>c : { g(): void; }
>{ g() { this.g(); } } : { g(): void; }
g() {
>g : () => void
this.g();
>this.g() : void
>this.g : () => void
>this : { g(): void; }
>g : () => void
}
},
get d() {
>d : number
return this.a;
>this.a : number
>this : { a: number; f(): number; b: string; c: { g(): void; }; readonly d: number; e: string; }
>a : number
},
get e() {
>e : string
return this.b;
>this.b : string
>this : { a: number; f(): number; b: string; c: { g(): void; }; readonly d: number; e: string; }
>b : string
},
set e(value) {
>e : string
>value : string
this.b = value;
>this.b = value : string
>this.b : string
>this : { a: number; f(): number; b: string; c: { g(): void; }; readonly d: number; e: string; }
>b : string
>value : string
}
};
// In methods of an object literal with a contextual type, 'this' has the
// contextual type.
type Point = {
>Point : Point
x: number;
>x : number
y: number;
>y : number
moveBy(dx: number, dy: number): void;
>moveBy : (dx: number, dy: number) => void
>dx : number
>dy : number
}
let p1: Point = {
>p1 : Point
>Point : Point
>{ x: 10, y: 20, moveBy(dx, dy) { this.x += dx; this.y += dy; }} : { x: number; y: number; moveBy(dx: number, dy: number): void; }
x: 10,
>x : number
>10 : 10
y: 20,
>y : number
>20 : 20
moveBy(dx, dy) {
>moveBy : (dx: number, dy: number) => void
>dx : number
>dy : number
this.x += dx;
>this.x += dx : number
>this.x : number
>this : Point
>x : number
>dx : number
this.y += dy;
>this.y += dy : number
>this.y : number
>this : Point
>y : number
>dy : number
}
};
declare function f1(p: Point): void;
>f1 : (p: Point) => void
>p : Point
>Point : Point
f1({
>f1({ x: 10, y: 20, moveBy(dx, dy) { this.x += dx; this.y += dy; }}) : void
>f1 : (p: Point) => void
>{ x: 10, y: 20, moveBy(dx, dy) { this.x += dx; this.y += dy; }} : { x: number; y: number; moveBy(dx: number, dy: number): void; }
x: 10,
>x : number
>10 : 10
y: 20,
>y : number
>20 : 20
moveBy(dx, dy) {
>moveBy : (dx: number, dy: number) => void
>dx : number
>dy : number
this.x += dx;
>this.x += dx : number
>this.x : number
>this : Point
>x : number
>dx : number
this.y += dy;
>this.y += dy : number
>this.y : number
>this : Point
>y : number
>dy : number
}
});
// In methods of an object literal with a contextual type that includes some
// ThisType<T>, 'this' is of type T.
type ObjectDescriptor<D, M> = {
>ObjectDescriptor : ObjectDescriptor<D, M>
>D : D
>M : M
data?: D;
>data : D
>D : D
methods?: M & ThisType<D & M>; // Type of 'this' in methods is D & M
>methods : M & ThisType<D & M>
>M : M
>ThisType : ThisType<T>
>D : D
>M : M
}
declare function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M;
>makeObject : <D, M>(desc: ObjectDescriptor<D, M>) => D & M
>D : D
>M : M
>desc : ObjectDescriptor<D, M>
>ObjectDescriptor : ObjectDescriptor<D, M>
>D : D
>M : M
>D : D
>M : M
let x1 = makeObject({
>x1 : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; }
>makeObject({ data: { x: 0, y: 0 }, methods: { moveBy(dx: number, dy: number) { this.x += dx; // Strongly typed this this.y += dy; // Strongly typed this } }}) : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; }
>makeObject : <D, M>(desc: ObjectDescriptor<D, M>) => D & M
>{ data: { x: 0, y: 0 }, methods: { moveBy(dx: number, dy: number) { this.x += dx; // Strongly typed this this.y += dy; // Strongly typed this } }} : { data: { x: number; y: number; }; methods: { moveBy(dx: number, dy: number): void; }; }
data: { x: 0, y: 0 },
>data : { x: number; y: number; }
>{ x: 0, y: 0 } : { x: number; y: number; }
>x : number
>0 : 0
>y : number
>0 : 0
methods: {
>methods : { moveBy(dx: number, dy: number): void; }
>{ moveBy(dx: number, dy: number) { this.x += dx; // Strongly typed this this.y += dy; // Strongly typed this } } : { moveBy(dx: number, dy: number): void; }
moveBy(dx: number, dy: number) {
>moveBy : (dx: number, dy: number) => void
>dx : number
>dy : number
this.x += dx; // Strongly typed this
>this.x += dx : number
>this.x : number
>this : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; }
>x : number
>dx : number
this.y += dy; // Strongly typed this
>this.y += dy : number
>this.y : number
>this : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; }
>y : number
>dy : number
}
}
});
// In methods contained in an object literal with a contextual type that includes
// some ThisType<T>, 'this' is of type T.
type ObjectDescriptor2<D, M> = ThisType<D & M> & {
>ObjectDescriptor2 : ObjectDescriptor2<D, M>
>D : D
>M : M
>ThisType : ThisType<T>
>D : D
>M : M
data?: D;
>data : D
>D : D
methods?: M;
>methods : M
>M : M
}
declare function makeObject2<D, M>(desc: ObjectDescriptor<D, M>): D & M;
>makeObject2 : <D, M>(desc: ObjectDescriptor<D, M>) => D & M
>D : D
>M : M
>desc : ObjectDescriptor<D, M>
>ObjectDescriptor : ObjectDescriptor<D, M>
>D : D
>M : M
>D : D
>M : M
let x2 = makeObject2({
>x2 : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; }
>makeObject2({ data: { x: 0, y: 0 }, methods: { moveBy(dx: number, dy: number) { this.x += dx; // Strongly typed this this.y += dy; // Strongly typed this } }}) : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; }
>makeObject2 : <D, M>(desc: ObjectDescriptor<D, M>) => D & M
>{ data: { x: 0, y: 0 }, methods: { moveBy(dx: number, dy: number) { this.x += dx; // Strongly typed this this.y += dy; // Strongly typed this } }} : { data: { x: number; y: number; }; methods: { moveBy(dx: number, dy: number): void; }; }
data: { x: 0, y: 0 },
>data : { x: number; y: number; }
>{ x: 0, y: 0 } : { x: number; y: number; }
>x : number
>0 : 0
>y : number
>0 : 0
methods: {
>methods : { moveBy(dx: number, dy: number): void; }
>{ moveBy(dx: number, dy: number) { this.x += dx; // Strongly typed this this.y += dy; // Strongly typed this } } : { moveBy(dx: number, dy: number): void; }
moveBy(dx: number, dy: number) {
>moveBy : (dx: number, dy: number) => void
>dx : number
>dy : number
this.x += dx; // Strongly typed this
>this.x += dx : number
>this.x : number
>this : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; }
>x : number
>dx : number
this.y += dy; // Strongly typed this
>this.y += dy : number
>this.y : number
>this : { x: number; y: number; } & { moveBy(dx: number, dy: number): void; }
>y : number
>dy : number
}
}
});
// Proof of concept for typing of Vue.js
type Accessors<T> = { [K in keyof T]: (() => T[K]) | Computed<T[K]> };
>Accessors : Accessors<T>
>T : T
>K : K
>T : T
>T : T
>K : K
>Computed : Computed<T>
>T : T
>K : K
type Dictionary<T> = { [x: string]: T }
>Dictionary : Dictionary<T>
>T : T
>x : string
>T : T
type Computed<T> = {
>Computed : Computed<T>
>T : T
get?(): T;
>get : () => T
>T : T
set?(value: T): void;
>set : (value: T) => void
>value : T
>T : T
}
type VueOptions<D, M, P> = ThisType<D & M & P> & {
>VueOptions : VueOptions<D, M, P>
>D : D
>M : M
>P : P
>ThisType : ThisType<T>
>D : D
>M : M
>P : P
data?: D | (() => D);
>data : D | (() => D)
>D : D
>D : D
methods?: M;
>methods : M
>M : M
computed?: Accessors<P>;
>computed : Accessors<P>
>Accessors : Accessors<T>
>P : P
}
declare const Vue: new <D, M, P>(options: VueOptions<D, M, P>) => D & M & P;
>Vue : new <D, M, P>(options: VueOptions<D, M, P>) => D & M & P
>D : D
>M : M
>P : P
>options : VueOptions<D, M, P>
>VueOptions : VueOptions<D, M, P>
>D : D
>M : M
>P : P
>D : D
>M : M
>P : P
let vue = new Vue({
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>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: number; hello: string; }
>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; }; }; }
data: () => ({ x: 1, y: 2 }),
>data : () => { x: number; y: number; }
>() => ({ x: 1, y: 2 }) : () => { x: number; y: number; }
>({ x: 1, y: 2 }) : { x: number; y: number; }
>{ x: 1, y: 2 } : { x: number; y: number; }
>x : number
>1 : 1
>y : number
>2 : 2
methods: {
>methods : { f(x: string): number; }
>{ f(x: string) { return this.x; } } : { f(x: string): number; }
f(x: string) {
>f : (x: string) => number
>x : string
return this.x;
>this.x : number
>this : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>x : number
}
},
computed: {
>computed : { test(): number; hello: { get(): string; set(value: string): void; }; }
>{ test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } } : { test(): number; hello: { get(): string; set(value: string): void; }; }
test(): number {
>test : () => number
return this.x;
>this.x : number
>this : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>x : number
},
hello: {
>hello : { get(): string; set(value: string): void; }
>{ get() { return "hi"; }, set(value: string) { } } : { get(): string; set(value: string): void; }
get() {
>get : () => string
return "hi";
>"hi" : "hi"
},
set(value: string) {
>set : (value: string) => void
>value : string
}
}
}
});
vue;
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
vue.x;
>vue.x : number
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>x : number
vue.f("abc");
>vue.f("abc") : number
>vue.f : (x: string) => number
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>f : (x: string) => number
>"abc" : "abc"
vue.test;
>vue.test : number
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>test : number
vue.hello;
>vue.hello : string
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>hello : string

View File

@ -0,0 +1,144 @@
// @declaration: true
// @noImplicitAny: true
// @noImplicitThis: true
// @target: es5
// In methods of an object literal with no contextual type, 'this' has the type
// of the object literal.
let obj1 = {
a: 1,
f() {
return this.a;
},
b: "hello",
c: {
g() {
this.g();
}
},
get d() {
return this.a;
},
get e() {
return this.b;
},
set e(value) {
this.b = value;
}
};
// In methods of an object literal with a contextual type, 'this' has the
// contextual type.
type Point = {
x: number;
y: number;
moveBy(dx: number, dy: number): void;
}
let p1: Point = {
x: 10,
y: 20,
moveBy(dx, dy) {
this.x += dx;
this.y += dy;
}
};
declare function f1(p: Point): void;
f1({
x: 10,
y: 20,
moveBy(dx, dy) {
this.x += dx;
this.y += dy;
}
});
// In methods of an object literal with a contextual type that includes some
// ThisType<T>, 'this' is of type T.
type ObjectDescriptor<D, M> = {
data?: D;
methods?: M & ThisType<D & M>; // Type of 'this' in methods is D & M
}
declare function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M;
let x1 = makeObject({
data: { x: 0, y: 0 },
methods: {
moveBy(dx: number, dy: number) {
this.x += dx; // Strongly typed this
this.y += dy; // Strongly typed this
}
}
});
// In methods contained in an object literal with a contextual type that includes
// some ThisType<T>, 'this' is of type T.
type ObjectDescriptor2<D, M> = ThisType<D & M> & {
data?: D;
methods?: M;
}
declare function makeObject2<D, M>(desc: ObjectDescriptor<D, M>): D & M;
let x2 = makeObject2({
data: { x: 0, y: 0 },
methods: {
moveBy(dx: number, dy: number) {
this.x += dx; // Strongly typed this
this.y += dy; // Strongly typed this
}
}
});
// Proof of concept for typing of Vue.js
type Accessors<T> = { [K in keyof T]: (() => T[K]) | Computed<T[K]> };
type Dictionary<T> = { [x: string]: T }
type Computed<T> = {
get?(): T;
set?(value: T): void;
}
type VueOptions<D, M, P> = ThisType<D & M & P> & {
data?: D | (() => D);
methods?: M;
computed?: Accessors<P>;
}
declare const Vue: new <D, M, P>(options: VueOptions<D, M, P>) => D & M & P;
let vue = 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) {
}
}
}
});
vue;
vue.x;
vue.f("abc");
vue.test;
vue.hello;