1//// [keyofAndIndexedAccess.ts] 2class Shape { 3 name: string; 4 width: number; 5 height: number; 6 visible: boolean; 7} 8 9class TaggedShape extends Shape { 10 tag: string; 11} 12 13class Item { 14 name: string; 15 price: number; 16} 17 18class Options { 19 visible: "yes" | "no"; 20} 21 22type Dictionary<T> = { [x: string]: T }; 23type NumericallyIndexed<T> = { [x: number]: T }; 24 25const enum E { A, B, C } 26 27type K00 = keyof any; // string 28type K01 = keyof string; // "toString" | "charAt" | ... 29type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ... 30type K03 = keyof boolean; // "valueOf" 31type K04 = keyof void; // never 32type K05 = keyof undefined; // never 33type K06 = keyof null; // never 34type K07 = keyof never; // string | number | symbol 35type K08 = keyof unknown; // never 36 37type K10 = keyof Shape; // "name" | "width" | "height" | "visible" 38type K11 = keyof Shape[]; // "length" | "toString" | ... 39type K12 = keyof Dictionary<Shape>; // string 40type K13 = keyof {}; // never 41type K14 = keyof Object; // "constructor" | "toString" | ... 42type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ... 43type K16 = keyof [string, number]; // "0" | "1" | "length" | "toString" | ... 44type K17 = keyof (Shape | Item); // "name" 45type K18 = keyof (Shape & Item); // "name" | "width" | "height" | "visible" | "price" 46type K19 = keyof NumericallyIndexed<Shape> // never 47 48type KeyOf<T> = keyof T; 49 50type K20 = KeyOf<Shape>; // "name" | "width" | "height" | "visible" 51type K21 = KeyOf<Dictionary<Shape>>; // string 52 53type NAME = "name"; 54type WIDTH_OR_HEIGHT = "width" | "height"; 55 56type Q10 = Shape["name"]; // string 57type Q11 = Shape["width" | "height"]; // number 58type Q12 = Shape["name" | "visible"]; // string | boolean 59 60type Q20 = Shape[NAME]; // string 61type Q21 = Shape[WIDTH_OR_HEIGHT]; // number 62 63type Q30 = [string, number][0]; // string 64type Q31 = [string, number][1]; // number 65type Q32 = [string, number][number]; // string | number 66type Q33 = [string, number][E.A]; // string 67type Q34 = [string, number][E.B]; // number 68type Q35 = [string, number]["0"]; // string 69type Q36 = [string, number]["1"]; // string 70 71type Q40 = (Shape | Options)["visible"]; // boolean | "yes" | "no" 72type Q41 = (Shape & Options)["visible"]; // true & "yes" | true & "no" | false & "yes" | false & "no" 73 74type Q50 = Dictionary<Shape>["howdy"]; // Shape 75type Q51 = Dictionary<Shape>[123]; // Shape 76type Q52 = Dictionary<Shape>[E.B]; // Shape 77 78declare let cond: boolean; 79 80function getProperty<T, K extends keyof T>(obj: T, key: K) { 81 return obj[key]; 82} 83 84function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]) { 85 obj[key] = value; 86} 87 88function f10(shape: Shape) { 89 let name = getProperty(shape, "name"); // string 90 let widthOrHeight = getProperty(shape, cond ? "width" : "height"); // number 91 let nameOrVisible = getProperty(shape, cond ? "name" : "visible"); // string | boolean 92 setProperty(shape, "name", "rectangle"); 93 setProperty(shape, cond ? "width" : "height", 10); 94 setProperty(shape, cond ? "name" : "visible", true); // Technically not safe 95} 96 97function f11(a: Shape[]) { 98 let len = getProperty(a, "length"); // number 99 setProperty(a, "length", len); 100} 101 102function f12(t: [Shape, boolean]) { 103 let len = getProperty(t, "length"); 104 let s2 = getProperty(t, "0"); // Shape 105 let b2 = getProperty(t, "1"); // boolean 106} 107 108function f13(foo: any, bar: any) { 109 let x = getProperty(foo, "x"); // any 110 let y = getProperty(foo, "100"); // any 111 let z = getProperty(foo, bar); // any 112} 113 114class Component<PropType> { 115 props: PropType; 116 getProperty<K extends keyof PropType>(key: K) { 117 return this.props[key]; 118 } 119 setProperty<K extends keyof PropType>(key: K, value: PropType[K]) { 120 this.props[key] = value; 121 } 122} 123 124function f20(component: Component<Shape>) { 125 let name = component.getProperty("name"); // string 126 let widthOrHeight = component.getProperty(cond ? "width" : "height"); // number 127 let nameOrVisible = component.getProperty(cond ? "name" : "visible"); // string | boolean 128 component.setProperty("name", "rectangle"); 129 component.setProperty(cond ? "width" : "height", 10) 130 component.setProperty(cond ? "name" : "visible", true); // Technically not safe 131} 132 133function pluck<T, K extends keyof T>(array: T[], key: K) { 134 return array.map(x => x[key]); 135} 136 137function f30(shapes: Shape[]) { 138 let names = pluck(shapes, "name"); // string[] 139 let widths = pluck(shapes, "width"); // number[] 140 let nameOrVisibles = pluck(shapes, cond ? "name" : "visible"); // (string | boolean)[] 141} 142 143function f31<K extends keyof Shape>(key: K) { 144 const shape: Shape = { name: "foo", width: 5, height: 10, visible: true }; 145 return shape[key]; // Shape[K] 146} 147 148function f32<K extends "width" | "height">(key: K) { 149 const shape: Shape = { name: "foo", width: 5, height: 10, visible: true }; 150 return shape[key]; // Shape[K] 151} 152 153function f33<S extends Shape, K extends keyof S>(shape: S, key: K) { 154 let name = getProperty(shape, "name"); 155 let prop = getProperty(shape, key); 156 return prop; 157} 158 159function f34(ts: TaggedShape) { 160 let tag1 = f33(ts, "tag"); 161 let tag2 = getProperty(ts, "tag"); 162} 163 164class C { 165 public x: string; 166 protected y: string; 167 private z: string; 168} 169 170// Indexed access expressions have always permitted access to private and protected members. 171// For consistency we also permit such access in indexed access types. 172function f40(c: C) { 173 type X = C["x"]; 174 type Y = C["y"]; 175 type Z = C["z"]; 176 let x: X = c["x"]; 177 let y: Y = c["y"]; 178 let z: Z = c["z"]; 179} 180 181function f50<T>(k: keyof T, s: string) { 182 const x1 = s as keyof T; 183 const x2 = k as string; 184} 185 186function f51<T, K extends keyof T>(k: K, s: string) { 187 const x1 = s as keyof T; 188 const x2 = k as string; 189} 190 191function f52<T>(obj: { [x: string]: boolean }, k: Exclude<keyof T, symbol>, s: string, n: number) { 192 const x1 = obj[s]; 193 const x2 = obj[n]; 194 const x3 = obj[k]; 195} 196 197function f53<T, K extends Exclude<keyof T, symbol>>(obj: { [x: string]: boolean }, k: K, s: string, n: number) { 198 const x1 = obj[s]; 199 const x2 = obj[n]; 200 const x3 = obj[k]; 201} 202 203function f54<T>(obj: T, key: keyof T) { 204 for (let s in obj[key]) { 205 } 206 const b = "foo" in obj[key]; 207} 208 209function f55<T, K extends keyof T>(obj: T, key: K) { 210 for (let s in obj[key]) { 211 } 212 const b = "foo" in obj[key]; 213} 214 215function f60<T>(source: T, target: T) { 216 for (let k in source) { 217 target[k] = source[k]; 218 } 219} 220 221function f70(func: <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void) { 222 func<{ a: any, b: any }, { a: any, c: any }>('a', 'a'); 223 func<{ a: any, b: any }, { a: any, c: any }>('a', 'b'); 224 func<{ a: any, b: any }, { a: any, c: any }>('a', 'c'); 225} 226 227function f71(func: <T, U>(x: T, y: U) => Partial<T & U>) { 228 let x = func({ a: 1, b: "hello" }, { c: true }); 229 x.a; // number | undefined 230 x.b; // string | undefined 231 x.c; // boolean | undefined 232} 233 234function f72(func: <T, U, K extends keyof T | keyof U>(x: T, y: U, k: K) => (T & U)[K]) { 235 let a = func({ a: 1, b: "hello" }, { c: true }, 'a'); // number 236 let b = func({ a: 1, b: "hello" }, { c: true }, 'b'); // string 237 let c = func({ a: 1, b: "hello" }, { c: true }, 'c'); // boolean 238} 239 240function f73(func: <T, U, K extends keyof (T & U)>(x: T, y: U, k: K) => (T & U)[K]) { 241 let a = func({ a: 1, b: "hello" }, { c: true }, 'a'); // number 242 let b = func({ a: 1, b: "hello" }, { c: true }, 'b'); // string 243 let c = func({ a: 1, b: "hello" }, { c: true }, 'c'); // boolean 244} 245 246function f74(func: <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]) { 247 let a = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'a'); // number 248 let b = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'b'); // string | boolean 249} 250 251function f80<T extends { a: { x: any } }>(obj: T) { 252 let a1 = obj.a; // { x: any } 253 let a2 = obj['a']; // { x: any } 254 let a3 = obj['a'] as T['a']; // T["a"] 255 let x1 = obj.a.x; // any 256 let x2 = obj['a']['x']; // any 257 let x3 = obj['a']['x'] as T['a']['x']; // T["a"]["x"] 258} 259 260function f81<T extends { a: { x: any } }>(obj: T) { 261 return obj['a']['x'] as T['a']['x']; 262} 263 264function f82() { 265 let x1 = f81({ a: { x: "hello" } }); // string 266 let x2 = f81({ a: { x: 42 } }); // number 267} 268 269function f83<T extends { [x: string]: { x: any } }, K extends keyof T>(obj: T, key: K) { 270 return obj[key]['x'] as T[K]['x']; 271} 272 273function f84() { 274 let x1 = f83({ foo: { x: "hello" } }, "foo"); // string 275 let x2 = f83({ bar: { x: 42 } }, "bar"); // number 276} 277 278class C1 { 279 x: number; 280 get<K extends keyof this>(key: K) { 281 return this[key]; 282 } 283 set<K extends keyof this>(key: K, value: this[K]) { 284 this[key] = value; 285 } 286 foo() { 287 let x1 = this.x; // number 288 let x2 = this["x"]; // number 289 let x3 = this.get("x"); // this["x"] 290 let x4 = getProperty(this, "x"); // this["x"] 291 this.x = 42; 292 this["x"] = 42; 293 this.set("x", 42); 294 setProperty(this, "x", 42); 295 } 296} 297 298type S2 = { 299 a: string; 300 b: string; 301}; 302 303function f90<T extends S2, K extends keyof S2>(x1: S2[keyof S2], x2: T[keyof S2], x3: S2[K]) { 304 x1 = x2; 305 x1 = x3; 306 x2 = x1; 307 x2 = x3; 308 x3 = x1; 309 x3 = x2; 310 x1.length; 311 x2.length; 312 x3.length; 313} 314 315function f91<T, K extends keyof T>(x: T, y: T[keyof T], z: T[K]) { 316 let a: {}; 317 a = x; 318 a = y; 319 a = z; 320} 321 322function f92<T, K extends keyof T>(x: T, y: T[keyof T], z: T[K]) { 323 let a: {} | null | undefined; 324 a = x; 325 a = y; 326 a = z; 327} 328 329// Repros from #12011 330 331class Base { 332 get<K extends keyof this>(prop: K) { 333 return this[prop]; 334 } 335 set<K extends keyof this>(prop: K, value: this[K]) { 336 this[prop] = value; 337 } 338} 339 340class Person extends Base { 341 parts: number; 342 constructor(parts: number) { 343 super(); 344 this.set("parts", parts); 345 } 346 getParts() { 347 return this.get("parts") 348 } 349} 350 351class OtherPerson { 352 parts: number; 353 constructor(parts: number) { 354 setProperty(this, "parts", parts); 355 } 356 getParts() { 357 return getProperty(this, "parts") 358 } 359} 360 361// Modified repro from #12544 362 363function path<T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; 364function path<T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; 365function path<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; 366function path(obj: any, ...keys: (string | number)[]): any; 367function path(obj: any, ...keys: (string | number)[]): any { 368 let result = obj; 369 for (let k of keys) { 370 result = result[k]; 371 } 372 return result; 373} 374 375type Thing = { 376 a: { x: number, y: string }, 377 b: boolean 378}; 379 380 381function f1(thing: Thing) { 382 let x1 = path(thing, 'a'); // { x: number, y: string } 383 let x2 = path(thing, 'a', 'y'); // string 384 let x3 = path(thing, 'b'); // boolean 385 let x4 = path(thing, ...['a', 'x']); // any 386} 387 388// Repro from comment in #12114 389 390const assignTo2 = <T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) => 391 (value: T[K1][K2]) => object[key1][key2] = value; 392 393// Modified repro from #12573 394 395declare function one<T>(handler: (t: T) => void): T 396var empty = one(() => {}) // inferred as {}, expected 397 398type Handlers<T> = { [K in keyof T]: (t: T[K]) => void } 399declare function on<T>(handlerHash: Handlers<T>): T 400var hashOfEmpty1 = on({ test: () => {} }); // {} 401var hashOfEmpty2 = on({ test: (x: boolean) => {} }); // { test: boolean } 402 403// Repro from #12624 404 405interface Options1<Data, Computed> { 406 data?: Data 407 computed?: Computed; 408} 409 410declare class Component1<Data, Computed> { 411 constructor(options: Options1<Data, Computed>); 412 get<K extends keyof (Data & Computed)>(key: K): (Data & Computed)[K]; 413} 414 415let c1 = new Component1({ 416 data: { 417 hello: "" 418 } 419}); 420 421c1.get("hello"); 422 423// Repro from #12625 424 425interface Options2<Data, Computed> { 426 data?: Data 427 computed?: Computed; 428} 429 430declare class Component2<Data, Computed> { 431 constructor(options: Options2<Data, Computed>); 432 get<K extends keyof Data | keyof Computed>(key: K): (Data & Computed)[K]; 433} 434 435// Repro from #12641 436 437interface R { 438 p: number; 439} 440 441function f<K extends keyof R>(p: K) { 442 let a: any; 443 a[p].add; // any 444} 445 446// Repro from #12651 447 448type MethodDescriptor = { 449 name: string; 450 args: any[]; 451 returnValue: any; 452} 453 454declare function dispatchMethod<M extends MethodDescriptor>(name: M['name'], args: M['args']): M['returnValue']; 455 456type SomeMethodDescriptor = { 457 name: "someMethod"; 458 args: [string, number]; 459 returnValue: string[]; 460} 461 462let result = dispatchMethod<SomeMethodDescriptor>("someMethod", ["hello", 35]); 463 464// Repro from #13073 465 466type KeyTypes = "a" | "b" 467let MyThingy: { [key in KeyTypes]: string[] }; 468 469function addToMyThingy<S extends KeyTypes>(key: S) { 470 MyThingy[key].push("a"); 471} 472 473// Repro from #13102 474 475type Handler<T> = { 476 onChange: (name: keyof T) => void; 477}; 478 479function onChangeGenericFunction<T>(handler: Handler<T & {preset: number}>) { 480 handler.onChange('preset') 481} 482 483// Repro from #13285 484 485function updateIds<T extends Record<K, string>, K extends string>( 486 obj: T, 487 idFields: K[], 488 idMapping: Partial<Record<T[K], T[K]>> 489): Record<K, string> { 490 for (const idField of idFields) { 491 const newId: T[K] | undefined = idMapping[obj[idField]]; 492 if (newId) { 493 obj[idField] = newId; 494 } 495 } 496 return obj; 497} 498 499// Repro from #13285 500 501function updateIds2<T extends { [x: string]: string }, K extends keyof T>( 502 obj: T, 503 key: K, 504 stringMap: { [oldId: string]: string } 505) { 506 var x = obj[key]; 507 stringMap[x]; // Should be OK. 508} 509 510// Repro from #13514 511 512declare function head<T extends Array<any>>(list: T): T[0]; 513 514// Repro from #13604 515 516class A<T> { 517 props: T & { foo: string }; 518} 519 520class B extends A<{ x: number}> { 521 f(p: this["props"]) { 522 p.x; 523 } 524} 525 526// Repro from #13749 527 528class Form<T> { 529 private childFormFactories: {[K in keyof T]: (v: T[K]) => Form<T[K]>} 530 531 public set<K extends keyof T>(prop: K, value: T[K]) { 532 this.childFormFactories[prop](value) 533 } 534} 535 536// Repro from #13787 537 538class SampleClass<P> { 539 public props: Readonly<P>; 540 constructor(props: P) { 541 this.props = Object.freeze(props); 542 } 543} 544 545interface Foo { 546 foo: string; 547} 548 549declare function merge<T, U>(obj1: T, obj2: U): T & U; 550 551class AnotherSampleClass<T> extends SampleClass<T & Foo> { 552 constructor(props: T) { 553 const foo: Foo = { foo: "bar" }; 554 super(merge(props, foo)); 555 } 556 557 public brokenMethod() { 558 this.props.foo.concat; 559 } 560} 561new AnotherSampleClass({}); 562 563// Positive repro from #17166 564function f3<T, K extends Extract<keyof T, string>>(t: T, k: K, tk: T[K]): void { 565 for (let key in t) { 566 key = k // ok, K ==> keyof T 567 t[key] = tk; // ok, T[K] ==> T[keyof T] 568 } 569} 570 571// # 21185 572type Predicates<TaggedRecord> = { 573 [T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T] 574} 575 576// Repros from #23592 577 578type Example<T extends { [K in keyof T]: { prop: any } }> = { [K in keyof T]: T[K]["prop"] }; 579type Result = Example<{ a: { prop: string }; b: { prop: number } }>; 580 581type Helper2<T> = { [K in keyof T]: Extract<T[K], { prop: any }> }; 582type Example2<T> = { [K in keyof Helper2<T>]: Helper2<T>[K]["prop"] }; 583type Result2 = Example2<{ 1: { prop: string }; 2: { prop: number } }>; 584 585// Repro from #23618 586 587type DBBoolTable<K extends string> = { [k in K]: 0 | 1 } 588enum Flag { 589 FLAG_1 = "flag_1", 590 FLAG_2 = "flag_2" 591} 592 593type SimpleDBRecord<Flag extends string> = { staticField: number } & DBBoolTable<Flag> 594function getFlagsFromSimpleRecord<Flag extends string>(record: SimpleDBRecord<Flag>, flags: Flag[]) { 595 return record[flags[0]]; 596} 597 598type DynamicDBRecord<Flag extends string> = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable<Flag> 599function getFlagsFromDynamicRecord<Flag extends string>(record: DynamicDBRecord<Flag>, flags: Flag[]) { 600 return record[flags[0]]; 601} 602 603// Repro from #21368 604 605interface I { 606 foo: string; 607} 608 609declare function take<T>(p: T): void; 610 611function fn<T extends I, K extends keyof T>(o: T, k: K) { 612 take<{} | null | undefined>(o[k]); 613 take<any>(o[k]); 614} 615 616// Repro from #23133 617 618class Unbounded<T> { 619 foo(x: T[keyof T]) { 620 let y: {} | undefined | null = x; 621 } 622} 623 624// Repro from #23940 625 626interface I7 { 627 x: any; 628} 629type Foo7<T extends number> = T; 630declare function f7<K extends keyof I7>(type: K): Foo7<I7[K]>; 631 632// Repro from #21770 633 634type Dict<T extends string> = { [key in T]: number }; 635type DictDict<V extends string, T extends string> = { [key in V]: Dict<T> }; 636 637function ff1<V extends string, T extends string>(dd: DictDict<V, T>, k1: V, k2: T): number { 638 return dd[k1][k2]; 639} 640 641function ff2<V extends string, T extends string>(dd: DictDict<V, T>, k1: V, k2: T): number { 642 const d: Dict<T> = dd[k1]; 643 return d[k2]; 644} 645 646// Repro from #26409 647 648const cf1 = <T extends { [P in K]: string; } & { cool: string; }, K extends keyof T>(t: T, k: K) => 649{ 650 const s: string = t[k]; 651 t.cool; 652}; 653 654const cf2 = <T extends { [P in K | "cool"]: string; }, K extends keyof T>(t: T, k: K) => 655{ 656 const s: string = t[k]; 657 t.cool; 658}; 659 660 661//// [keyofAndIndexedAccess.js] 662var __extends = (this && this.__extends) || (function () { 663 var extendStatics = function (d, b) { 664 extendStatics = Object.setPrototypeOf || 665 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 666 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 667 return extendStatics(d, b); 668 }; 669 return function (d, b) { 670 if (typeof b !== "function" && b !== null) 671 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); 672 extendStatics(d, b); 673 function __() { this.constructor = d; } 674 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 675 }; 676})(); 677var __spreadArray = (this && this.__spreadArray) || function (to, from) { 678 for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) 679 to[j] = from[i]; 680 return to; 681}; 682var Shape = /** @class */ (function () { 683 function Shape() { 684 } 685 return Shape; 686}()); 687var TaggedShape = /** @class */ (function (_super) { 688 __extends(TaggedShape, _super); 689 function TaggedShape() { 690 return _super !== null && _super.apply(this, arguments) || this; 691 } 692 return TaggedShape; 693}(Shape)); 694var Item = /** @class */ (function () { 695 function Item() { 696 } 697 return Item; 698}()); 699var Options = /** @class */ (function () { 700 function Options() { 701 } 702 return Options; 703}()); 704function getProperty(obj, key) { 705 return obj[key]; 706} 707function setProperty(obj, key, value) { 708 obj[key] = value; 709} 710function f10(shape) { 711 var name = getProperty(shape, "name"); // string 712 var widthOrHeight = getProperty(shape, cond ? "width" : "height"); // number 713 var nameOrVisible = getProperty(shape, cond ? "name" : "visible"); // string | boolean 714 setProperty(shape, "name", "rectangle"); 715 setProperty(shape, cond ? "width" : "height", 10); 716 setProperty(shape, cond ? "name" : "visible", true); // Technically not safe 717} 718function f11(a) { 719 var len = getProperty(a, "length"); // number 720 setProperty(a, "length", len); 721} 722function f12(t) { 723 var len = getProperty(t, "length"); 724 var s2 = getProperty(t, "0"); // Shape 725 var b2 = getProperty(t, "1"); // boolean 726} 727function f13(foo, bar) { 728 var x = getProperty(foo, "x"); // any 729 var y = getProperty(foo, "100"); // any 730 var z = getProperty(foo, bar); // any 731} 732var Component = /** @class */ (function () { 733 function Component() { 734 } 735 Component.prototype.getProperty = function (key) { 736 return this.props[key]; 737 }; 738 Component.prototype.setProperty = function (key, value) { 739 this.props[key] = value; 740 }; 741 return Component; 742}()); 743function f20(component) { 744 var name = component.getProperty("name"); // string 745 var widthOrHeight = component.getProperty(cond ? "width" : "height"); // number 746 var nameOrVisible = component.getProperty(cond ? "name" : "visible"); // string | boolean 747 component.setProperty("name", "rectangle"); 748 component.setProperty(cond ? "width" : "height", 10); 749 component.setProperty(cond ? "name" : "visible", true); // Technically not safe 750} 751function pluck(array, key) { 752 return array.map(function (x) { return x[key]; }); 753} 754function f30(shapes) { 755 var names = pluck(shapes, "name"); // string[] 756 var widths = pluck(shapes, "width"); // number[] 757 var nameOrVisibles = pluck(shapes, cond ? "name" : "visible"); // (string | boolean)[] 758} 759function f31(key) { 760 var shape = { name: "foo", width: 5, height: 10, visible: true }; 761 return shape[key]; // Shape[K] 762} 763function f32(key) { 764 var shape = { name: "foo", width: 5, height: 10, visible: true }; 765 return shape[key]; // Shape[K] 766} 767function f33(shape, key) { 768 var name = getProperty(shape, "name"); 769 var prop = getProperty(shape, key); 770 return prop; 771} 772function f34(ts) { 773 var tag1 = f33(ts, "tag"); 774 var tag2 = getProperty(ts, "tag"); 775} 776var C = /** @class */ (function () { 777 function C() { 778 } 779 return C; 780}()); 781// Indexed access expressions have always permitted access to private and protected members. 782// For consistency we also permit such access in indexed access types. 783function f40(c) { 784 var x = c["x"]; 785 var y = c["y"]; 786 var z = c["z"]; 787} 788function f50(k, s) { 789 var x1 = s; 790 var x2 = k; 791} 792function f51(k, s) { 793 var x1 = s; 794 var x2 = k; 795} 796function f52(obj, k, s, n) { 797 var x1 = obj[s]; 798 var x2 = obj[n]; 799 var x3 = obj[k]; 800} 801function f53(obj, k, s, n) { 802 var x1 = obj[s]; 803 var x2 = obj[n]; 804 var x3 = obj[k]; 805} 806function f54(obj, key) { 807 for (var s in obj[key]) { 808 } 809 var b = "foo" in obj[key]; 810} 811function f55(obj, key) { 812 for (var s in obj[key]) { 813 } 814 var b = "foo" in obj[key]; 815} 816function f60(source, target) { 817 for (var k in source) { 818 target[k] = source[k]; 819 } 820} 821function f70(func) { 822 func('a', 'a'); 823 func('a', 'b'); 824 func('a', 'c'); 825} 826function f71(func) { 827 var x = func({ a: 1, b: "hello" }, { c: true }); 828 x.a; // number | undefined 829 x.b; // string | undefined 830 x.c; // boolean | undefined 831} 832function f72(func) { 833 var a = func({ a: 1, b: "hello" }, { c: true }, 'a'); // number 834 var b = func({ a: 1, b: "hello" }, { c: true }, 'b'); // string 835 var c = func({ a: 1, b: "hello" }, { c: true }, 'c'); // boolean 836} 837function f73(func) { 838 var a = func({ a: 1, b: "hello" }, { c: true }, 'a'); // number 839 var b = func({ a: 1, b: "hello" }, { c: true }, 'b'); // string 840 var c = func({ a: 1, b: "hello" }, { c: true }, 'c'); // boolean 841} 842function f74(func) { 843 var a = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'a'); // number 844 var b = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'b'); // string | boolean 845} 846function f80(obj) { 847 var a1 = obj.a; // { x: any } 848 var a2 = obj['a']; // { x: any } 849 var a3 = obj['a']; // T["a"] 850 var x1 = obj.a.x; // any 851 var x2 = obj['a']['x']; // any 852 var x3 = obj['a']['x']; // T["a"]["x"] 853} 854function f81(obj) { 855 return obj['a']['x']; 856} 857function f82() { 858 var x1 = f81({ a: { x: "hello" } }); // string 859 var x2 = f81({ a: { x: 42 } }); // number 860} 861function f83(obj, key) { 862 return obj[key]['x']; 863} 864function f84() { 865 var x1 = f83({ foo: { x: "hello" } }, "foo"); // string 866 var x2 = f83({ bar: { x: 42 } }, "bar"); // number 867} 868var C1 = /** @class */ (function () { 869 function C1() { 870 } 871 C1.prototype.get = function (key) { 872 return this[key]; 873 }; 874 C1.prototype.set = function (key, value) { 875 this[key] = value; 876 }; 877 C1.prototype.foo = function () { 878 var x1 = this.x; // number 879 var x2 = this["x"]; // number 880 var x3 = this.get("x"); // this["x"] 881 var x4 = getProperty(this, "x"); // this["x"] 882 this.x = 42; 883 this["x"] = 42; 884 this.set("x", 42); 885 setProperty(this, "x", 42); 886 }; 887 return C1; 888}()); 889function f90(x1, x2, x3) { 890 x1 = x2; 891 x1 = x3; 892 x2 = x1; 893 x2 = x3; 894 x3 = x1; 895 x3 = x2; 896 x1.length; 897 x2.length; 898 x3.length; 899} 900function f91(x, y, z) { 901 var a; 902 a = x; 903 a = y; 904 a = z; 905} 906function f92(x, y, z) { 907 var a; 908 a = x; 909 a = y; 910 a = z; 911} 912// Repros from #12011 913var Base = /** @class */ (function () { 914 function Base() { 915 } 916 Base.prototype.get = function (prop) { 917 return this[prop]; 918 }; 919 Base.prototype.set = function (prop, value) { 920 this[prop] = value; 921 }; 922 return Base; 923}()); 924var Person = /** @class */ (function (_super) { 925 __extends(Person, _super); 926 function Person(parts) { 927 var _this = _super.call(this) || this; 928 _this.set("parts", parts); 929 return _this; 930 } 931 Person.prototype.getParts = function () { 932 return this.get("parts"); 933 }; 934 return Person; 935}(Base)); 936var OtherPerson = /** @class */ (function () { 937 function OtherPerson(parts) { 938 setProperty(this, "parts", parts); 939 } 940 OtherPerson.prototype.getParts = function () { 941 return getProperty(this, "parts"); 942 }; 943 return OtherPerson; 944}()); 945function path(obj) { 946 var keys = []; 947 for (var _i = 1; _i < arguments.length; _i++) { 948 keys[_i - 1] = arguments[_i]; 949 } 950 var result = obj; 951 for (var _a = 0, keys_1 = keys; _a < keys_1.length; _a++) { 952 var k = keys_1[_a]; 953 result = result[k]; 954 } 955 return result; 956} 957function f1(thing) { 958 var x1 = path(thing, 'a'); // { x: number, y: string } 959 var x2 = path(thing, 'a', 'y'); // string 960 var x3 = path(thing, 'b'); // boolean 961 var x4 = path.apply(void 0, __spreadArray([thing], ['a', 'x'])); // any 962} 963// Repro from comment in #12114 964var assignTo2 = function (object, key1, key2) { 965 return function (value) { return object[key1][key2] = value; }; 966}; 967var empty = one(function () { }); // inferred as {}, expected 968var hashOfEmpty1 = on({ test: function () { } }); // {} 969var hashOfEmpty2 = on({ test: function (x) { } }); // { test: boolean } 970var c1 = new Component1({ 971 data: { 972 hello: "" 973 } 974}); 975c1.get("hello"); 976function f(p) { 977 var a; 978 a[p].add; // any 979} 980var result = dispatchMethod("someMethod", ["hello", 35]); 981var MyThingy; 982function addToMyThingy(key) { 983 MyThingy[key].push("a"); 984} 985function onChangeGenericFunction(handler) { 986 handler.onChange('preset'); 987} 988// Repro from #13285 989function updateIds(obj, idFields, idMapping) { 990 for (var _i = 0, idFields_1 = idFields; _i < idFields_1.length; _i++) { 991 var idField = idFields_1[_i]; 992 var newId = idMapping[obj[idField]]; 993 if (newId) { 994 obj[idField] = newId; 995 } 996 } 997 return obj; 998} 999// Repro from #13285 1000function updateIds2(obj, key, stringMap) { 1001 var x = obj[key]; 1002 stringMap[x]; // Should be OK. 1003} 1004// Repro from #13604 1005var A = /** @class */ (function () { 1006 function A() { 1007 } 1008 return A; 1009}()); 1010var B = /** @class */ (function (_super) { 1011 __extends(B, _super); 1012 function B() { 1013 return _super !== null && _super.apply(this, arguments) || this; 1014 } 1015 B.prototype.f = function (p) { 1016 p.x; 1017 }; 1018 return B; 1019}(A)); 1020// Repro from #13749 1021var Form = /** @class */ (function () { 1022 function Form() { 1023 } 1024 Form.prototype.set = function (prop, value) { 1025 this.childFormFactories[prop](value); 1026 }; 1027 return Form; 1028}()); 1029// Repro from #13787 1030var SampleClass = /** @class */ (function () { 1031 function SampleClass(props) { 1032 this.props = Object.freeze(props); 1033 } 1034 return SampleClass; 1035}()); 1036var AnotherSampleClass = /** @class */ (function (_super) { 1037 __extends(AnotherSampleClass, _super); 1038 function AnotherSampleClass(props) { 1039 var _this = this; 1040 var foo = { foo: "bar" }; 1041 _this = _super.call(this, merge(props, foo)) || this; 1042 return _this; 1043 } 1044 AnotherSampleClass.prototype.brokenMethod = function () { 1045 this.props.foo.concat; 1046 }; 1047 return AnotherSampleClass; 1048}(SampleClass)); 1049new AnotherSampleClass({}); 1050// Positive repro from #17166 1051function f3(t, k, tk) { 1052 for (var key in t) { 1053 key = k; // ok, K ==> keyof T 1054 t[key] = tk; // ok, T[K] ==> T[keyof T] 1055 } 1056} 1057var Flag; 1058(function (Flag) { 1059 Flag["FLAG_1"] = "flag_1"; 1060 Flag["FLAG_2"] = "flag_2"; 1061})(Flag || (Flag = {})); 1062function getFlagsFromSimpleRecord(record, flags) { 1063 return record[flags[0]]; 1064} 1065function getFlagsFromDynamicRecord(record, flags) { 1066 return record[flags[0]]; 1067} 1068function fn(o, k) { 1069 take(o[k]); 1070 take(o[k]); 1071} 1072// Repro from #23133 1073var Unbounded = /** @class */ (function () { 1074 function Unbounded() { 1075 } 1076 Unbounded.prototype.foo = function (x) { 1077 var y = x; 1078 }; 1079 return Unbounded; 1080}()); 1081function ff1(dd, k1, k2) { 1082 return dd[k1][k2]; 1083} 1084function ff2(dd, k1, k2) { 1085 var d = dd[k1]; 1086 return d[k2]; 1087} 1088// Repro from #26409 1089var cf1 = function (t, k) { 1090 var s = t[k]; 1091 t.cool; 1092}; 1093var cf2 = function (t, k) { 1094 var s = t[k]; 1095 t.cool; 1096}; 1097 1098 1099//// [keyofAndIndexedAccess.d.ts] 1100declare class Shape { 1101 name: string; 1102 width: number; 1103 height: number; 1104 visible: boolean; 1105} 1106declare class TaggedShape extends Shape { 1107 tag: string; 1108} 1109declare class Item { 1110 name: string; 1111 price: number; 1112} 1113declare class Options { 1114 visible: "yes" | "no"; 1115} 1116declare type Dictionary<T> = { 1117 [x: string]: T; 1118}; 1119declare type NumericallyIndexed<T> = { 1120 [x: number]: T; 1121}; 1122declare const enum E { 1123 A = 0, 1124 B = 1, 1125 C = 2 1126} 1127declare type K00 = keyof any; 1128declare type K01 = keyof string; 1129declare type K02 = keyof number; 1130declare type K03 = keyof boolean; 1131declare type K04 = keyof void; 1132declare type K05 = keyof undefined; 1133declare type K06 = keyof null; 1134declare type K07 = keyof never; 1135declare type K08 = keyof unknown; 1136declare type K10 = keyof Shape; 1137declare type K11 = keyof Shape[]; 1138declare type K12 = keyof Dictionary<Shape>; 1139declare type K13 = keyof {}; 1140declare type K14 = keyof Object; 1141declare type K15 = keyof E; 1142declare type K16 = keyof [string, number]; 1143declare type K17 = keyof (Shape | Item); 1144declare type K18 = keyof (Shape & Item); 1145declare type K19 = keyof NumericallyIndexed<Shape>; 1146declare type KeyOf<T> = keyof T; 1147declare type K20 = KeyOf<Shape>; 1148declare type K21 = KeyOf<Dictionary<Shape>>; 1149declare type NAME = "name"; 1150declare type WIDTH_OR_HEIGHT = "width" | "height"; 1151declare type Q10 = Shape["name"]; 1152declare type Q11 = Shape["width" | "height"]; 1153declare type Q12 = Shape["name" | "visible"]; 1154declare type Q20 = Shape[NAME]; 1155declare type Q21 = Shape[WIDTH_OR_HEIGHT]; 1156declare type Q30 = [string, number][0]; 1157declare type Q31 = [string, number][1]; 1158declare type Q32 = [string, number][number]; 1159declare type Q33 = [string, number][E.A]; 1160declare type Q34 = [string, number][E.B]; 1161declare type Q35 = [string, number]["0"]; 1162declare type Q36 = [string, number]["1"]; 1163declare type Q40 = (Shape | Options)["visible"]; 1164declare type Q41 = (Shape & Options)["visible"]; 1165declare type Q50 = Dictionary<Shape>["howdy"]; 1166declare type Q51 = Dictionary<Shape>[123]; 1167declare type Q52 = Dictionary<Shape>[E.B]; 1168declare let cond: boolean; 1169declare function getProperty<T, K extends keyof T>(obj: T, key: K): T[K]; 1170declare function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]): void; 1171declare function f10(shape: Shape): void; 1172declare function f11(a: Shape[]): void; 1173declare function f12(t: [Shape, boolean]): void; 1174declare function f13(foo: any, bar: any): void; 1175declare class Component<PropType> { 1176 props: PropType; 1177 getProperty<K extends keyof PropType>(key: K): PropType[K]; 1178 setProperty<K extends keyof PropType>(key: K, value: PropType[K]): void; 1179} 1180declare function f20(component: Component<Shape>): void; 1181declare function pluck<T, K extends keyof T>(array: T[], key: K): T[K][]; 1182declare function f30(shapes: Shape[]): void; 1183declare function f31<K extends keyof Shape>(key: K): Shape[K]; 1184declare function f32<K extends "width" | "height">(key: K): Shape[K]; 1185declare function f33<S extends Shape, K extends keyof S>(shape: S, key: K): S[K]; 1186declare function f34(ts: TaggedShape): void; 1187declare class C { 1188 x: string; 1189 protected y: string; 1190 private z; 1191} 1192declare function f40(c: C): void; 1193declare function f50<T>(k: keyof T, s: string): void; 1194declare function f51<T, K extends keyof T>(k: K, s: string): void; 1195declare function f52<T>(obj: { 1196 [x: string]: boolean; 1197}, k: Exclude<keyof T, symbol>, s: string, n: number): void; 1198declare function f53<T, K extends Exclude<keyof T, symbol>>(obj: { 1199 [x: string]: boolean; 1200}, k: K, s: string, n: number): void; 1201declare function f54<T>(obj: T, key: keyof T): void; 1202declare function f55<T, K extends keyof T>(obj: T, key: K): void; 1203declare function f60<T>(source: T, target: T): void; 1204declare function f70(func: <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void): void; 1205declare function f71(func: <T, U>(x: T, y: U) => Partial<T & U>): void; 1206declare function f72(func: <T, U, K extends keyof T | keyof U>(x: T, y: U, k: K) => (T & U)[K]): void; 1207declare function f73(func: <T, U, K extends keyof (T & U)>(x: T, y: U, k: K) => (T & U)[K]): void; 1208declare function f74(func: <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]): void; 1209declare function f80<T extends { 1210 a: { 1211 x: any; 1212 }; 1213}>(obj: T): void; 1214declare function f81<T extends { 1215 a: { 1216 x: any; 1217 }; 1218}>(obj: T): T["a"]["x"]; 1219declare function f82(): void; 1220declare function f83<T extends { 1221 [x: string]: { 1222 x: any; 1223 }; 1224}, K extends keyof T>(obj: T, key: K): T[K]["x"]; 1225declare function f84(): void; 1226declare class C1 { 1227 x: number; 1228 get<K extends keyof this>(key: K): this[K]; 1229 set<K extends keyof this>(key: K, value: this[K]): void; 1230 foo(): void; 1231} 1232declare type S2 = { 1233 a: string; 1234 b: string; 1235}; 1236declare function f90<T extends S2, K extends keyof S2>(x1: S2[keyof S2], x2: T[keyof S2], x3: S2[K]): void; 1237declare function f91<T, K extends keyof T>(x: T, y: T[keyof T], z: T[K]): void; 1238declare function f92<T, K extends keyof T>(x: T, y: T[keyof T], z: T[K]): void; 1239declare class Base { 1240 get<K extends keyof this>(prop: K): this[K]; 1241 set<K extends keyof this>(prop: K, value: this[K]): void; 1242} 1243declare class Person extends Base { 1244 parts: number; 1245 constructor(parts: number); 1246 getParts(): this["parts"]; 1247} 1248declare class OtherPerson { 1249 parts: number; 1250 constructor(parts: number); 1251 getParts(): this["parts"]; 1252} 1253declare function path<T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; 1254declare function path<T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; 1255declare function path<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; 1256declare function path(obj: any, ...keys: (string | number)[]): any; 1257declare type Thing = { 1258 a: { 1259 x: number; 1260 y: string; 1261 }; 1262 b: boolean; 1263}; 1264declare function f1(thing: Thing): void; 1265declare const assignTo2: <T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) => (value: T[K1][K2]) => T[K1][K2]; 1266declare function one<T>(handler: (t: T) => void): T; 1267declare var empty: unknown; 1268declare type Handlers<T> = { 1269 [K in keyof T]: (t: T[K]) => void; 1270}; 1271declare function on<T>(handlerHash: Handlers<T>): T; 1272declare var hashOfEmpty1: { 1273 test: unknown; 1274}; 1275declare var hashOfEmpty2: { 1276 test: boolean; 1277}; 1278interface Options1<Data, Computed> { 1279 data?: Data; 1280 computed?: Computed; 1281} 1282declare class Component1<Data, Computed> { 1283 constructor(options: Options1<Data, Computed>); 1284 get<K extends keyof (Data & Computed)>(key: K): (Data & Computed)[K]; 1285} 1286declare let c1: Component1<{ 1287 hello: string; 1288}, unknown>; 1289interface Options2<Data, Computed> { 1290 data?: Data; 1291 computed?: Computed; 1292} 1293declare class Component2<Data, Computed> { 1294 constructor(options: Options2<Data, Computed>); 1295 get<K extends keyof Data | keyof Computed>(key: K): (Data & Computed)[K]; 1296} 1297interface R { 1298 p: number; 1299} 1300declare function f<K extends keyof R>(p: K): void; 1301declare type MethodDescriptor = { 1302 name: string; 1303 args: any[]; 1304 returnValue: any; 1305}; 1306declare function dispatchMethod<M extends MethodDescriptor>(name: M['name'], args: M['args']): M['returnValue']; 1307declare type SomeMethodDescriptor = { 1308 name: "someMethod"; 1309 args: [string, number]; 1310 returnValue: string[]; 1311}; 1312declare let result: string[]; 1313declare type KeyTypes = "a" | "b"; 1314declare let MyThingy: { 1315 [key in KeyTypes]: string[]; 1316}; 1317declare function addToMyThingy<S extends KeyTypes>(key: S): void; 1318declare type Handler<T> = { 1319 onChange: (name: keyof T) => void; 1320}; 1321declare function onChangeGenericFunction<T>(handler: Handler<T & { 1322 preset: number; 1323}>): void; 1324declare function updateIds<T extends Record<K, string>, K extends string>(obj: T, idFields: K[], idMapping: Partial<Record<T[K], T[K]>>): Record<K, string>; 1325declare function updateIds2<T extends { 1326 [x: string]: string; 1327}, K extends keyof T>(obj: T, key: K, stringMap: { 1328 [oldId: string]: string; 1329}): void; 1330declare function head<T extends Array<any>>(list: T): T[0]; 1331declare class A<T> { 1332 props: T & { 1333 foo: string; 1334 }; 1335} 1336declare class B extends A<{ 1337 x: number; 1338}> { 1339 f(p: this["props"]): void; 1340} 1341declare class Form<T> { 1342 private childFormFactories; 1343 set<K extends keyof T>(prop: K, value: T[K]): void; 1344} 1345declare class SampleClass<P> { 1346 props: Readonly<P>; 1347 constructor(props: P); 1348} 1349interface Foo { 1350 foo: string; 1351} 1352declare function merge<T, U>(obj1: T, obj2: U): T & U; 1353declare class AnotherSampleClass<T> extends SampleClass<T & Foo> { 1354 constructor(props: T); 1355 brokenMethod(): void; 1356} 1357declare function f3<T, K extends Extract<keyof T, string>>(t: T, k: K, tk: T[K]): void; 1358declare type Predicates<TaggedRecord> = { 1359 [T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]; 1360}; 1361declare type Example<T extends { 1362 [K in keyof T]: { 1363 prop: any; 1364 }; 1365}> = { 1366 [K in keyof T]: T[K]["prop"]; 1367}; 1368declare type Result = Example<{ 1369 a: { 1370 prop: string; 1371 }; 1372 b: { 1373 prop: number; 1374 }; 1375}>; 1376declare type Helper2<T> = { 1377 [K in keyof T]: Extract<T[K], { 1378 prop: any; 1379 }>; 1380}; 1381declare type Example2<T> = { 1382 [K in keyof Helper2<T>]: Helper2<T>[K]["prop"]; 1383}; 1384declare type Result2 = Example2<{ 1385 1: { 1386 prop: string; 1387 }; 1388 2: { 1389 prop: number; 1390 }; 1391}>; 1392declare type DBBoolTable<K extends string> = { 1393 [k in K]: 0 | 1; 1394}; 1395declare enum Flag { 1396 FLAG_1 = "flag_1", 1397 FLAG_2 = "flag_2" 1398} 1399declare type SimpleDBRecord<Flag extends string> = { 1400 staticField: number; 1401} & DBBoolTable<Flag>; 1402declare function getFlagsFromSimpleRecord<Flag extends string>(record: SimpleDBRecord<Flag>, flags: Flag[]): SimpleDBRecord<Flag>[Flag]; 1403declare type DynamicDBRecord<Flag extends string> = ({ 1404 dynamicField: number; 1405} | { 1406 dynamicField: string; 1407}) & DBBoolTable<Flag>; 1408declare function getFlagsFromDynamicRecord<Flag extends string>(record: DynamicDBRecord<Flag>, flags: Flag[]): DynamicDBRecord<Flag>[Flag]; 1409interface I { 1410 foo: string; 1411} 1412declare function take<T>(p: T): void; 1413declare function fn<T extends I, K extends keyof T>(o: T, k: K): void; 1414declare class Unbounded<T> { 1415 foo(x: T[keyof T]): void; 1416} 1417interface I7 { 1418 x: any; 1419} 1420declare type Foo7<T extends number> = T; 1421declare function f7<K extends keyof I7>(type: K): Foo7<I7[K]>; 1422declare type Dict<T extends string> = { 1423 [key in T]: number; 1424}; 1425declare type DictDict<V extends string, T extends string> = { 1426 [key in V]: Dict<T>; 1427}; 1428declare function ff1<V extends string, T extends string>(dd: DictDict<V, T>, k1: V, k2: T): number; 1429declare function ff2<V extends string, T extends string>(dd: DictDict<V, T>, k1: V, k2: T): number; 1430declare const cf1: <T extends { [P in K]: string; } & { 1431 cool: string; 1432}, K extends keyof T>(t: T, k: K) => void; 1433declare const cf2: <T extends { [P in K | "cool"]: string; }, K extends keyof T>(t: T, k: K) => void; 1434