type Shape = { kind : "circle" ; radius : number ; } | { kind : "square" ; size : number ; } | { kind : "rectangle" ; width : number ; height : number ; } ; type Named = { name : string ; } ; let shape ; let optionalShape ; let namedShape ; let optionalNamedShape ; type Thing < T > = { value : T ; } ; type ArrayThing < U > = Thing < U [ ] > ; type StringArrayThing = ArrayThing < string > ; declare let t1 ; declare let t2 ; declare let t3 ; function foo < T , K extends keyof T > ( obj , key ) { let x ; }