=== tests/cases/conformance/types/typeParameters/typeParameterLists/propertyAccessOnTypeParameterWithConstraints2.ts === // generic types should behave as if they have properties of their constraint type class A { >A : A foo(): string { return ''; } >foo : () => string >'' : string } class B extends A { >B : B >A : A bar(): string { >bar : () => string return ''; >'' : string } } class C { >C : C >U : U >A : A >T : T >A : A f() { >f : () => string var x: U; >x : U >U : U var a = x['foo'](); // should be string >a : string >x['foo']() : string >x['foo'] : () => string >x : U >'foo' : string return a + x.foo(); >a + x.foo() : string >a : string >x.foo() : string >x.foo : () => string >x : U >foo : () => string } g(x: U) { >g : (x: U) => string >x : U >U : U var a = x['foo'](); // should be string >a : string >x['foo']() : string >x['foo'] : () => string >x : U >'foo' : string return a + x.foo(); >a + x.foo() : string >a : string >x.foo() : string >x.foo : () => string >x : U >foo : () => string } } //class C { // f() { // var x: U; // var a = x['foo'](); // should be string // return a + x.foo(); // } // g(x: U) { // var a = x['foo'](); // should be string // return a + x.foo(); // } //} var r1 = (new C()).f(); >r1 : string >(new C()).f() : string >(new C()).f : () => string >(new C()) : C >new C() : C >C : typeof C >B : B >A : A >f : () => string var r1b = (new C()).g(new B()); >r1b : string >(new C()).g(new B()) : string >(new C()).g : (x: B) => string >(new C()) : C >new C() : C >C : typeof C >B : B >A : A >g : (x: B) => string >new B() : B >B : typeof B interface I { >I : I >U : U >A : A >T : T >A : A foo: U; >foo : U >U : U } //interface I { // foo: U; //} var i: I; >i : I >I : I >B : B >A : A var r2 = i.foo.foo(); >r2 : string >i.foo.foo() : string >i.foo.foo : () => string >i.foo : B >i : I >foo : B >foo : () => string var r2b = i.foo['foo'](); >r2b : string >i.foo['foo']() : string >i.foo['foo'] : () => string >i.foo : B >i : I >foo : B >'foo' : string var a: { >a : { (): U; (x: U): U; (x: U, y: T): U; } (): U; >U : U >A : A >T : T >A : A >U : U (x: U): U; >U : U >A : A >T : T >A : A >x : U >U : U >U : U (x: U, y: T): U; >U : U >A : A >T : T >A : A >x : U >U : U >y : T >T : T >U : U } //var a: { // (): U; // (x: U): U; // (x: U, y: T): U; //} var r3 = a().foo(); >r3 : string >a().foo() : string >a().foo : () => string >a() : A >a : { (): U; (x: U): U; (x: U, y: T): U; } >A : A >A : A >foo : () => string var r3b = a()['foo'](); >r3b : string >a()['foo']() : string >a()['foo'] : () => string >a() : A >a : { (): U; (x: U): U; (x: U, y: T): U; } >'foo' : string // parameter supplied for type argument inference to succeed var aB = new B(); >aB : B >new B() : B >B : typeof B var r3c = a(aB, aB).foo(); >r3c : string >a(aB, aB).foo() : string >a(aB, aB).foo : () => string >a(aB, aB) : B >a : { (): U; (x: U): U; (x: U, y: T): U; } >aB : B >aB : B >foo : () => string var r3d = a(aB, aB)['foo'](); >r3d : string >a(aB, aB)['foo']() : string >a(aB, aB)['foo'] : () => string >a(aB, aB) : B >a : { (): U; (x: U): U; (x: U, y: T): U; } >aB : B >aB : B >'foo' : string var b = { >b : { foo: (x: U, y: T) => string; } >{ foo: (x: U, y: T) => { var a = x['foo'](); // should be string return a + x.foo(); }} : { foo: (x: U, y: T) => string; } foo: (x: U, y: T) => { >foo : (x: U, y: T) => string >(x: U, y: T) => { var a = x['foo'](); // should be string return a + x.foo(); } : (x: U, y: T) => string >U : U >A : A >T : T >A : A >x : U >U : U >y : T >T : T var a = x['foo'](); // should be string >a : string >x['foo']() : string >x['foo'] : () => string >x : U >'foo' : string return a + x.foo(); >a + x.foo() : string >a : string >x.foo() : string >x.foo : () => string >x : U >foo : () => string } } //var b = { // foo: (x: U, y: T) => { // var a = x['foo'](); // should be string // return a + x.foo(); // } //} var r4 = b.foo(aB, aB); // no inferences for T so constraint isn't satisfied, error >r4 : string >b.foo(aB, aB) : string >b.foo : (x: U, y: T) => string >b : { foo: (x: U, y: T) => string; } >foo : (x: U, y: T) => string >aB : B >aB : B