Closed
Description
I have two use cases that I cannot seem to type correctly in TypeScript. Both use cases involve functions that take a parameter of type "an object with any subset of the members of interface X".
Use case 1: options merging
interface Options {
a: string;
b: string;
}
const defaults: Options = {
a: "a",
b: "b"
}
function merge<T>(base: T, additional: <subtype of T>): T {
// clone all members of 'additional' onto 'base'
}
let opts: Options = merge<Options>(defaults, { b: "some other b" });
Use case 2: React state
See also https://facebook.github.io/react/docs/component-api.html
A React component is a class with three generic parameters Props, State and Context. The base class defines a setState(newState: State) method. In reality though, the setState() method accepts any sub-type of State.
This becomes particularly painful when having multiple layers of inheritance in React components:
BaseWidget.tsx
// one React component
class BaseWidget<P extends BaseWidget.Props, S extends BaseWidget.State, C extends BaseWidget.Context> extends ReactComponent<P, S, C> {
public componentWillMount()
// valid React call, TypeScript error 'argument of type foo is not assignable to parameter bar'
this.setState({ a: "string" });
}
}
module BaseWidget {
"use strict";
export interface Props extends React.Props<BaseWidget<Props, State, Context>> {
}
// note that all members must have ? on them to work
export interface State {
a?: string;
}
export interface Context {
}
}
export = BaseWidget