Merge pull request #13817 from Microsoft/fixIndexedAccessApparentType

Fix indexed access apparent type
This commit is contained in:
Anders Hejlsberg
2017-02-01 08:23:58 -10:00
committed by GitHub
5 changed files with 262 additions and 1 deletions

View File

@@ -4929,7 +4929,7 @@ namespace ts {
}
function getApparentTypeOfIntersectionType(type: IntersectionType) {
return type.resolvedIndexType || (type.resolvedApparentType = getTypeWithThisArgument(type, type));
return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type));
}
/**

View File

@@ -526,6 +526,33 @@ class Form<T> {
this.childFormFactories[prop](value)
}
}
// Repro from #13787
class SampleClass<P> {
public props: Readonly<P>;
constructor(props: P) {
this.props = Object.freeze(props);
}
}
interface Foo {
foo: string;
}
declare function merge<T, U>(obj1: T, obj2: U): T & U;
class AnotherSampleClass<T> extends SampleClass<T & Foo> {
constructor(props: T) {
const foo: Foo = { foo: "bar" };
super(merge(props, foo));
}
public brokenMethod() {
this.props.foo.concat;
}
}
new AnotherSampleClass({});
//// [keyofAndIndexedAccess.js]
@@ -881,6 +908,27 @@ var Form = (function () {
};
return Form;
}());
// Repro from #13787
var SampleClass = (function () {
function SampleClass(props) {
this.props = Object.freeze(props);
}
return SampleClass;
}());
var AnotherSampleClass = (function (_super) {
__extends(AnotherSampleClass, _super);
function AnotherSampleClass(props) {
var _this = this;
var foo = { foo: "bar" };
_this = _super.call(this, merge(props, foo)) || this;
return _this;
}
AnotherSampleClass.prototype.brokenMethod = function () {
this.props.foo.concat;
};
return AnotherSampleClass;
}(SampleClass));
new AnotherSampleClass({});
//// [keyofAndIndexedAccess.d.ts]
@@ -1127,3 +1175,15 @@ declare class Form<T> {
private childFormFactories;
set<K extends keyof T>(prop: K, value: T[K]): void;
}
declare class SampleClass<P> {
props: Readonly<P>;
constructor(props: P);
}
interface Foo {
foo: string;
}
declare function merge<T, U>(obj1: T, obj2: U): T & U;
declare class AnotherSampleClass<T> extends SampleClass<T & Foo> {
constructor(props: T);
brokenMethod(): void;
}

View File

@@ -1880,3 +1880,86 @@ class Form<T> {
}
}
// Repro from #13787
class SampleClass<P> {
>SampleClass : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1))
>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 530, 18))
public props: Readonly<P>;
>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 530, 18))
constructor(props: P) {
>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 532, 16))
>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 530, 18))
this.props = Object.freeze(props);
>this.props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
>this : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1))
>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
>Object.freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 532, 16))
}
}
interface Foo {
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 535, 1))
foo: string;
>foo : Symbol(Foo.foo, Decl(keyofAndIndexedAccess.ts, 537, 15))
}
declare function merge<T, U>(obj1: T, obj2: U): T & U;
>merge : Symbol(merge, Decl(keyofAndIndexedAccess.ts, 539, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 541, 23))
>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 541, 25))
>obj1 : Symbol(obj1, Decl(keyofAndIndexedAccess.ts, 541, 29))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 541, 23))
>obj2 : Symbol(obj2, Decl(keyofAndIndexedAccess.ts, 541, 37))
>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 541, 25))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 541, 23))
>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 541, 25))
class AnotherSampleClass<T> extends SampleClass<T & Foo> {
>AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 541, 54))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 543, 25))
>SampleClass : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 543, 25))
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 535, 1))
constructor(props: T) {
>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 544, 16))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 543, 25))
const foo: Foo = { foo: "bar" };
>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 545, 13))
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 535, 1))
>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 545, 26))
super(merge(props, foo));
>super : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1))
>merge : Symbol(merge, Decl(keyofAndIndexedAccess.ts, 539, 1))
>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 544, 16))
>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 545, 13))
}
public brokenMethod() {
>brokenMethod : Symbol(AnotherSampleClass.brokenMethod, Decl(keyofAndIndexedAccess.ts, 547, 5))
this.props.foo.concat;
>this.props.foo.concat : Symbol(String.concat, Decl(lib.d.ts, --, --))
>this.props.foo : Symbol(foo)
>this.props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
>this : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 541, 54))
>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
>foo : Symbol(foo)
>concat : Symbol(String.concat, Decl(lib.d.ts, --, --))
}
}
new AnotherSampleClass({});
>AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 541, 54))

View File

@@ -2204,3 +2204,94 @@ class Form<T> {
}
}
// Repro from #13787
class SampleClass<P> {
>SampleClass : SampleClass<P>
>P : P
public props: Readonly<P>;
>props : Readonly<P>
>Readonly : Readonly<T>
>P : P
constructor(props: P) {
>props : P
>P : P
this.props = Object.freeze(props);
>this.props = Object.freeze(props) : Readonly<P>
>this.props : Readonly<P>
>this : this
>props : Readonly<P>
>Object.freeze(props) : Readonly<P>
>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>props : P
}
}
interface Foo {
>Foo : Foo
foo: string;
>foo : string
}
declare function merge<T, U>(obj1: T, obj2: U): T & U;
>merge : <T, U>(obj1: T, obj2: U) => T & U
>T : T
>U : U
>obj1 : T
>T : T
>obj2 : U
>U : U
>T : T
>U : U
class AnotherSampleClass<T> extends SampleClass<T & Foo> {
>AnotherSampleClass : AnotherSampleClass<T>
>T : T
>SampleClass : SampleClass<T & Foo>
>T : T
>Foo : Foo
constructor(props: T) {
>props : T
>T : T
const foo: Foo = { foo: "bar" };
>foo : Foo
>Foo : Foo
>{ foo: "bar" } : { foo: string; }
>foo : string
>"bar" : "bar"
super(merge(props, foo));
>super(merge(props, foo)) : void
>super : typeof SampleClass
>merge(props, foo) : T & Foo
>merge : <T, U>(obj1: T, obj2: U) => T & U
>props : T
>foo : Foo
}
public brokenMethod() {
>brokenMethod : () => void
this.props.foo.concat;
>this.props.foo.concat : (...strings: string[]) => string
>this.props.foo : (T & Foo)["foo"]
>this.props : Readonly<T & Foo>
>this : this
>props : Readonly<T & Foo>
>foo : (T & Foo)["foo"]
>concat : (...strings: string[]) => string
}
}
new AnotherSampleClass({});
>new AnotherSampleClass({}) : AnotherSampleClass<{}>
>AnotherSampleClass : typeof AnotherSampleClass
>{} : {}

View File

@@ -527,3 +527,30 @@ class Form<T> {
this.childFormFactories[prop](value)
}
}
// Repro from #13787
class SampleClass<P> {
public props: Readonly<P>;
constructor(props: P) {
this.props = Object.freeze(props);
}
}
interface Foo {
foo: string;
}
declare function merge<T, U>(obj1: T, obj2: U): T & U;
class AnotherSampleClass<T> extends SampleClass<T & Foo> {
constructor(props: T) {
const foo: Foo = { foo: "bar" };
super(merge(props, foo));
}
public brokenMethod() {
this.props.foo.concat;
}
}
new AnotherSampleClass({});