Skip to content

Commit ddf4f45

Browse files
authored
Merge pull request #13817 from Microsoft/fixIndexedAccessApparentType
Fix indexed access apparent type
2 parents ddb6d99 + 97828b4 commit ddf4f45

File tree

5 files changed

+262
-1
lines changed

5 files changed

+262
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4929,7 +4929,7 @@ namespace ts {
49294929
}
49304930

49314931
function getApparentTypeOfIntersectionType(type: IntersectionType) {
4932-
return type.resolvedIndexType || (type.resolvedApparentType = getTypeWithThisArgument(type, type));
4932+
return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type));
49334933
}
49344934

49354935
/**

tests/baselines/reference/keyofAndIndexedAccess.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,33 @@ class Form<T> {
526526
this.childFormFactories[prop](value)
527527
}
528528
}
529+
530+
// Repro from #13787
531+
532+
class SampleClass<P> {
533+
public props: Readonly<P>;
534+
constructor(props: P) {
535+
this.props = Object.freeze(props);
536+
}
537+
}
538+
539+
interface Foo {
540+
foo: string;
541+
}
542+
543+
declare function merge<T, U>(obj1: T, obj2: U): T & U;
544+
545+
class AnotherSampleClass<T> extends SampleClass<T & Foo> {
546+
constructor(props: T) {
547+
const foo: Foo = { foo: "bar" };
548+
super(merge(props, foo));
549+
}
550+
551+
public brokenMethod() {
552+
this.props.foo.concat;
553+
}
554+
}
555+
new AnotherSampleClass({});
529556

530557

531558
//// [keyofAndIndexedAccess.js]
@@ -881,6 +908,27 @@ var Form = (function () {
881908
};
882909
return Form;
883910
}());
911+
// Repro from #13787
912+
var SampleClass = (function () {
913+
function SampleClass(props) {
914+
this.props = Object.freeze(props);
915+
}
916+
return SampleClass;
917+
}());
918+
var AnotherSampleClass = (function (_super) {
919+
__extends(AnotherSampleClass, _super);
920+
function AnotherSampleClass(props) {
921+
var _this = this;
922+
var foo = { foo: "bar" };
923+
_this = _super.call(this, merge(props, foo)) || this;
924+
return _this;
925+
}
926+
AnotherSampleClass.prototype.brokenMethod = function () {
927+
this.props.foo.concat;
928+
};
929+
return AnotherSampleClass;
930+
}(SampleClass));
931+
new AnotherSampleClass({});
884932

885933

886934
//// [keyofAndIndexedAccess.d.ts]
@@ -1127,3 +1175,15 @@ declare class Form<T> {
11271175
private childFormFactories;
11281176
set<K extends keyof T>(prop: K, value: T[K]): void;
11291177
}
1178+
declare class SampleClass<P> {
1179+
props: Readonly<P>;
1180+
constructor(props: P);
1181+
}
1182+
interface Foo {
1183+
foo: string;
1184+
}
1185+
declare function merge<T, U>(obj1: T, obj2: U): T & U;
1186+
declare class AnotherSampleClass<T> extends SampleClass<T & Foo> {
1187+
constructor(props: T);
1188+
brokenMethod(): void;
1189+
}

tests/baselines/reference/keyofAndIndexedAccess.symbols

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1880,3 +1880,86 @@ class Form<T> {
18801880
}
18811881
}
18821882

1883+
// Repro from #13787
1884+
1885+
class SampleClass<P> {
1886+
>SampleClass : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1))
1887+
>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 530, 18))
1888+
1889+
public props: Readonly<P>;
1890+
>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
1891+
>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
1892+
>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 530, 18))
1893+
1894+
constructor(props: P) {
1895+
>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 532, 16))
1896+
>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 530, 18))
1897+
1898+
this.props = Object.freeze(props);
1899+
>this.props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
1900+
>this : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1))
1901+
>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
1902+
>Object.freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
1903+
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
1904+
>freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
1905+
>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 532, 16))
1906+
}
1907+
}
1908+
1909+
interface Foo {
1910+
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 535, 1))
1911+
1912+
foo: string;
1913+
>foo : Symbol(Foo.foo, Decl(keyofAndIndexedAccess.ts, 537, 15))
1914+
}
1915+
1916+
declare function merge<T, U>(obj1: T, obj2: U): T & U;
1917+
>merge : Symbol(merge, Decl(keyofAndIndexedAccess.ts, 539, 1))
1918+
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 541, 23))
1919+
>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 541, 25))
1920+
>obj1 : Symbol(obj1, Decl(keyofAndIndexedAccess.ts, 541, 29))
1921+
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 541, 23))
1922+
>obj2 : Symbol(obj2, Decl(keyofAndIndexedAccess.ts, 541, 37))
1923+
>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 541, 25))
1924+
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 541, 23))
1925+
>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 541, 25))
1926+
1927+
class AnotherSampleClass<T> extends SampleClass<T & Foo> {
1928+
>AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 541, 54))
1929+
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 543, 25))
1930+
>SampleClass : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1))
1931+
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 543, 25))
1932+
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 535, 1))
1933+
1934+
constructor(props: T) {
1935+
>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 544, 16))
1936+
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 543, 25))
1937+
1938+
const foo: Foo = { foo: "bar" };
1939+
>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 545, 13))
1940+
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 535, 1))
1941+
>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 545, 26))
1942+
1943+
super(merge(props, foo));
1944+
>super : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 526, 1))
1945+
>merge : Symbol(merge, Decl(keyofAndIndexedAccess.ts, 539, 1))
1946+
>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 544, 16))
1947+
>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 545, 13))
1948+
}
1949+
1950+
public brokenMethod() {
1951+
>brokenMethod : Symbol(AnotherSampleClass.brokenMethod, Decl(keyofAndIndexedAccess.ts, 547, 5))
1952+
1953+
this.props.foo.concat;
1954+
>this.props.foo.concat : Symbol(String.concat, Decl(lib.d.ts, --, --))
1955+
>this.props.foo : Symbol(foo)
1956+
>this.props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
1957+
>this : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 541, 54))
1958+
>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 530, 22))
1959+
>foo : Symbol(foo)
1960+
>concat : Symbol(String.concat, Decl(lib.d.ts, --, --))
1961+
}
1962+
}
1963+
new AnotherSampleClass({});
1964+
>AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 541, 54))
1965+

tests/baselines/reference/keyofAndIndexedAccess.types

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2204,3 +2204,94 @@ class Form<T> {
22042204
}
22052205
}
22062206

2207+
// Repro from #13787
2208+
2209+
class SampleClass<P> {
2210+
>SampleClass : SampleClass<P>
2211+
>P : P
2212+
2213+
public props: Readonly<P>;
2214+
>props : Readonly<P>
2215+
>Readonly : Readonly<T>
2216+
>P : P
2217+
2218+
constructor(props: P) {
2219+
>props : P
2220+
>P : P
2221+
2222+
this.props = Object.freeze(props);
2223+
>this.props = Object.freeze(props) : Readonly<P>
2224+
>this.props : Readonly<P>
2225+
>this : this
2226+
>props : Readonly<P>
2227+
>Object.freeze(props) : Readonly<P>
2228+
>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
2229+
>Object : ObjectConstructor
2230+
>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
2231+
>props : P
2232+
}
2233+
}
2234+
2235+
interface Foo {
2236+
>Foo : Foo
2237+
2238+
foo: string;
2239+
>foo : string
2240+
}
2241+
2242+
declare function merge<T, U>(obj1: T, obj2: U): T & U;
2243+
>merge : <T, U>(obj1: T, obj2: U) => T & U
2244+
>T : T
2245+
>U : U
2246+
>obj1 : T
2247+
>T : T
2248+
>obj2 : U
2249+
>U : U
2250+
>T : T
2251+
>U : U
2252+
2253+
class AnotherSampleClass<T> extends SampleClass<T & Foo> {
2254+
>AnotherSampleClass : AnotherSampleClass<T>
2255+
>T : T
2256+
>SampleClass : SampleClass<T & Foo>
2257+
>T : T
2258+
>Foo : Foo
2259+
2260+
constructor(props: T) {
2261+
>props : T
2262+
>T : T
2263+
2264+
const foo: Foo = { foo: "bar" };
2265+
>foo : Foo
2266+
>Foo : Foo
2267+
>{ foo: "bar" } : { foo: string; }
2268+
>foo : string
2269+
>"bar" : "bar"
2270+
2271+
super(merge(props, foo));
2272+
>super(merge(props, foo)) : void
2273+
>super : typeof SampleClass
2274+
>merge(props, foo) : T & Foo
2275+
>merge : <T, U>(obj1: T, obj2: U) => T & U
2276+
>props : T
2277+
>foo : Foo
2278+
}
2279+
2280+
public brokenMethod() {
2281+
>brokenMethod : () => void
2282+
2283+
this.props.foo.concat;
2284+
>this.props.foo.concat : (...strings: string[]) => string
2285+
>this.props.foo : (T & Foo)["foo"]
2286+
>this.props : Readonly<T & Foo>
2287+
>this : this
2288+
>props : Readonly<T & Foo>
2289+
>foo : (T & Foo)["foo"]
2290+
>concat : (...strings: string[]) => string
2291+
}
2292+
}
2293+
new AnotherSampleClass({});
2294+
>new AnotherSampleClass({}) : AnotherSampleClass<{}>
2295+
>AnotherSampleClass : typeof AnotherSampleClass
2296+
>{} : {}
2297+

tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,3 +527,30 @@ class Form<T> {
527527
this.childFormFactories[prop](value)
528528
}
529529
}
530+
531+
// Repro from #13787
532+
533+
class SampleClass<P> {
534+
public props: Readonly<P>;
535+
constructor(props: P) {
536+
this.props = Object.freeze(props);
537+
}
538+
}
539+
540+
interface Foo {
541+
foo: string;
542+
}
543+
544+
declare function merge<T, U>(obj1: T, obj2: U): T & U;
545+
546+
class AnotherSampleClass<T> extends SampleClass<T & Foo> {
547+
constructor(props: T) {
548+
const foo: Foo = { foo: "bar" };
549+
super(merge(props, foo));
550+
}
551+
552+
public brokenMethod() {
553+
this.props.foo.concat;
554+
}
555+
}
556+
new AnotherSampleClass({});

0 commit comments

Comments
 (0)