1/* 2* Copyright (c) Microsoft Corporation. All rights reserved. 3* Copyright (c) 2023 Huawei Device Co., Ltd. 4* Licensed under the Apache License, Version 2.0 (the "License"); 5* you may not use this file except in compliance with the License. 6* You may obtain a copy of the License at 7* 8* http://www.apache.org/licenses/LICENSE-2.0 9* 10* Unless required by applicable law or agreed to in writing, software 11* distributed under the License is distributed on an "AS IS" BASIS, 12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13* See the License for the specific language governing permissions and 14* limitations under the License. 15* 16* This file has been modified by Huawei to verify type inference by adding verification statements. 17*/ 18 19// === tests/cases/conformance/types/typeParameters/typeParameterLists/propertyAccessOnTypeParameterWithConstraints2.ts === 20declare function AssertType(value:any, type:string):void; 21// generic types should behave as if they have properties of their constraint type 22 23class A { 24 foo(): string { 25AssertType('', "string"); 26return ''; 27} 28} 29 30class B extends A { 31 bar(): string { 32AssertType('', "string"); 33 return ''; 34 } 35} 36 37class C<U extends A, T extends A> { 38 f() { 39 let x: U; 40AssertType(x, "U"); 41 42 let a = x['foo'](); // should be string 43AssertType(a, "string"); 44AssertType(x['foo'](), "string"); 45AssertType(x['foo'], "() => string"); 46AssertType(x, "U"); 47AssertType('foo', "string"); 48 49AssertType(a + x.foo(), "string"); 50AssertType(a, "string"); 51AssertType(x.foo(), "string"); 52AssertType(x.foo, "() => string"); 53 return a + x.foo(); 54 } 55 56 g(x: U) { 57 let a = x['foo'](); // should be string 58AssertType(a, "string"); 59AssertType(x['foo'](), "string"); 60AssertType(x['foo'], "() => string"); 61AssertType(x, "U"); 62AssertType('foo', "string"); 63 64AssertType(a + x.foo(), "string"); 65AssertType(a, "string"); 66AssertType(x.foo(), "string"); 67AssertType(x.foo, "() => string"); 68 return a + x.foo(); 69 } 70} 71 72let r1 = (new C<B, A>()).f(); 73AssertType(r1, "string"); 74AssertType((new C<B, A>()).f(), "string"); 75AssertType((new C<B, A>()).f, "() => string"); 76 77let r1b = (new C<B, A>()).g(new B()); 78AssertType(r1b, "string"); 79AssertType((new C<B, A>()).g(new B()), "string"); 80AssertType((new C<B, A>()).g, "(B) => string"); 81AssertType(new B(), "B"); 82AssertType(B, "typeof B"); 83 84interface I<U extends A, T extends A> { 85 foo: U; 86} 87//interface I<U extends T, T extends A> { 88// foo: U; 89//} 90let i: I<B, A>; 91AssertType(i, "I<B, A>"); 92 93let r2 = i.foo.foo(); 94AssertType(r2, "string"); 95AssertType(i.foo.foo(), "string"); 96AssertType(i.foo.foo, "() => string"); 97 98let r2b = i.foo['foo'](); 99AssertType(r2b, "string"); 100AssertType(i.foo['foo'](), "string"); 101AssertType(i.foo['foo'], "() => string"); 102AssertType(i.foo, "B"); 103AssertType('foo', "string"); 104 105let a: { 106AssertType(a, "{ <U extends A, T extends A>(): U; <U extends A, T extends A>(U): U; <U extends A, T extends A>(U, T): U; }"); 107 108 <U extends A, T extends A>(): U; 109 <U extends A, T extends A>(x: U): U; 110AssertType(x, "U"); 111 112 <U extends A, T extends A>(x: U, y: T): U; 113AssertType(x, "U"); 114AssertType(y, "T"); 115} 116//let a: { 117// <U extends T, T extends A>(): U; 118// <U extends T, T extends A>(x: U): U; 119// <U extends T, T extends A>(x: U, y: T): U; 120//} 121let r3 = a<A, A>().foo(); 122AssertType(r3, "string"); 123AssertType(a<A, A>().foo(), "string"); 124AssertType(a<A, A>().foo, "() => string"); 125 126let r3b = a()['foo'](); 127AssertType(r3b, "string"); 128AssertType(a()['foo'](), "string"); 129AssertType(a()['foo'], "() => string"); 130AssertType(a(), "A"); 131AssertType(a, "{ <U extends A, T extends A>(): U; <U extends A, T extends A>(U): U; <U extends A, T extends A>(U, T): U; }"); 132AssertType('foo', "string"); 133 134// parameter supplied for type argument inference to succeed 135let aB = new B(); 136AssertType(aB, "B"); 137AssertType(new B(), "B"); 138AssertType(B, "typeof B"); 139 140let r3c = a(aB, aB).foo(); 141AssertType(r3c, "string"); 142AssertType(a(aB, aB).foo(), "string"); 143AssertType(a(aB, aB).foo, "() => string"); 144 145let r3d = a(aB, aB)['foo'](); 146AssertType(r3d, "string"); 147AssertType(a(aB, aB)['foo'](), "string"); 148AssertType(a(aB, aB)['foo'], "() => string"); 149AssertType(a(aB, aB), "B"); 150AssertType(a, "{ <U extends A, T extends A>(): U; <U extends A, T extends A>(U): U; <U extends A, T extends A>(U, T): U; }"); 151AssertType(aB, "B"); 152AssertType(aB, "B"); 153AssertType('foo', "string"); 154 155let b = { 156AssertType(b, "{ foo: <U extends A, T extends A>(U, T) => string; }"); 157AssertType({ foo: <U extends A, T extends A>(x: U, y: T) => { let a = x['foo'](); // should be string return a + x.foo(); }}, "{ foo: <U extends A, T extends A>(U, T) => string; }"); 158 159 foo: <U extends A, T extends A>(x: U, y: T) => { 160AssertType(foo, "<U extends A, T extends A>(U, T) => string"); 161AssertType(x, "U"); 162AssertType(y, "T"); 163AssertType(<U extends A, T extends A>(x: U, y: T) => { let a = x['foo'](); // should be string return a + x.foo(); }, "<U extends A, T extends A>(U, T) => string"); 164 165 let a = x['foo'](); // should be string 166AssertType(a, "string"); 167AssertType(x['foo'](), "string"); 168AssertType(x['foo'], "() => string"); 169AssertType(x, "U"); 170AssertType('foo', "string"); 171 172AssertType(a + x.foo(), "string"); 173AssertType(a, "string"); 174AssertType(x.foo(), "string"); 175AssertType(x.foo, "() => string"); 176 return a + x.foo(); 177 } 178} 179 180let r4 = b.foo(aB, aB); // no inferences for T so constraint isn't satisfied, error 181AssertType(r4, "string"); 182AssertType(b.foo(aB, aB), "string"); 183AssertType(b.foo, "<U extends A, T extends A>(U, T) => string"); 184AssertType(aB, "B"); 185AssertType(aB, "B"); 186 187 188