Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
interface Action<T> {
payload?: T;
type: string;
}
class EffectModule {
count = 1;
message = "hello!";
delay(input: Promise<number>) {
return input.then(i => ({
payload: `hello ${i}!`,
type: 'delay'
}));
}
setMessage(action: Action<Date>) {
return {
payload: action.payload!.getMilliseconds(),
type: "set-message"
};
}
}
// 修改 Connect 的类型,让 connected 的类型变成预期的类型
type Connect = (module: EffectModule) => ExtractContainer<EffectModule>
const connect: Connect = m => ({
delay: (input: number) => ({
type: 'delay',
payload: `hello 2`
}),
setMessage: (input: Date) => ({
type: "set-message",
payload: input.getMilliseconds()
})
});
type Connected = {
delay(input: number): Action<string>;
setMessage(action: Date): Action<number>;
};
type PickFuncKeys<T> = {
[K in keyof T]: T[K] extends Function ? K : never;
}[keyof T];
type ExtractContainer<P> = {
[K in PickFuncKeys<P>]:
P[K] extends (arg: Promise<infer T>) => Promise<infer U> ? (arg: T) => U :
P[K] extends (arg: Action<infer T>) => Action<infer U> ? (arg: T) => Action<U> :
never
}
export const connected: Connected = connect(new EffectModule());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment