// @noImplicitAny: true // @strictNullChecks: true // @jsx: preserve // @filename: index.tsx interface ActionsObject { [prop: string]: (state: State) => State; } interface Options { state?: State; view?: (state: State, actions: Actions) => any; actions: string | Actions; } declare function app>(obj: Options): void; app({ state: 100, actions: { foo: s => s // Should be typed number => number }, view: (s, a) => undefined as any, }); interface Bar { bar: (a: number) => void; } declare function foo(x: string | T): T; const y = foo({ bar(x) { // Should be typed number => void } }); interface Options2 { state?: State; view?: (state: State, actions: Actions) => any; actions?: Actions; } declare function app2>(obj: Options2): void; app2({ state: 100, actions: { foo: s => s // Should be typed number => number }, view: (s, a) => undefined as any, }); type ActionsArray = ((state: State) => State)[]; declare function app3>(obj: Options): void; app3({ state: 100, actions: [ s => s // Should be typed number => number ], view: (s, a) => undefined as any, }); namespace JSX { export interface Element {} export interface IntrinsicElements {} } interface ActionsObjectOr { [prop: string]: ((state: State) => State) | State; } declare function App4>(props: Options["actions"] & { state: State }): JSX.Element; const a = s} />; // TODO: should be number => number, but JSX resolution is missing an inferential pass