Extracting typescript signatures from an object into an interface
I have a habit where I seem to duplicate a lot of typings when passing information in redux. Is there any way to automatically generate the interface Props when they are all defined in ActionCreators? See the code below:
import { bindActionCreators, Dispatch } from "redux";
const ActionCreators = {
foo: (a: string): string => ("foo" + a),
bar: (a: number): string => ("bar" + a),
baz: (a: boolean): number => (a ? 256 : 123)
};
interface Props {
foo: (a: string) => string;
bar: (a: number) => string;
baz: (a: boolean) => number;
}
const mapDispatchToProps = (dispatch: Dispatch): Props => {
return bindActionCreators(ActionCreators, dispatch);
};
Understanding bindActionCreators is not required, the real issue here is getting all the signatures on ActionCreators the be extracted to an interface such as Props.
typescript interface react-redux typescript-typings
add a comment |
I have a habit where I seem to duplicate a lot of typings when passing information in redux. Is there any way to automatically generate the interface Props when they are all defined in ActionCreators? See the code below:
import { bindActionCreators, Dispatch } from "redux";
const ActionCreators = {
foo: (a: string): string => ("foo" + a),
bar: (a: number): string => ("bar" + a),
baz: (a: boolean): number => (a ? 256 : 123)
};
interface Props {
foo: (a: string) => string;
bar: (a: number) => string;
baz: (a: boolean) => number;
}
const mapDispatchToProps = (dispatch: Dispatch): Props => {
return bindActionCreators(ActionCreators, dispatch);
};
Understanding bindActionCreators is not required, the real issue here is getting all the signatures on ActionCreators the be extracted to an interface such as Props.
typescript interface react-redux typescript-typings
add a comment |
I have a habit where I seem to duplicate a lot of typings when passing information in redux. Is there any way to automatically generate the interface Props when they are all defined in ActionCreators? See the code below:
import { bindActionCreators, Dispatch } from "redux";
const ActionCreators = {
foo: (a: string): string => ("foo" + a),
bar: (a: number): string => ("bar" + a),
baz: (a: boolean): number => (a ? 256 : 123)
};
interface Props {
foo: (a: string) => string;
bar: (a: number) => string;
baz: (a: boolean) => number;
}
const mapDispatchToProps = (dispatch: Dispatch): Props => {
return bindActionCreators(ActionCreators, dispatch);
};
Understanding bindActionCreators is not required, the real issue here is getting all the signatures on ActionCreators the be extracted to an interface such as Props.
typescript interface react-redux typescript-typings
I have a habit where I seem to duplicate a lot of typings when passing information in redux. Is there any way to automatically generate the interface Props when they are all defined in ActionCreators? See the code below:
import { bindActionCreators, Dispatch } from "redux";
const ActionCreators = {
foo: (a: string): string => ("foo" + a),
bar: (a: number): string => ("bar" + a),
baz: (a: boolean): number => (a ? 256 : 123)
};
interface Props {
foo: (a: string) => string;
bar: (a: number) => string;
baz: (a: boolean) => number;
}
const mapDispatchToProps = (dispatch: Dispatch): Props => {
return bindActionCreators(ActionCreators, dispatch);
};
Understanding bindActionCreators is not required, the real issue here is getting all the signatures on ActionCreators the be extracted to an interface such as Props.
typescript interface react-redux typescript-typings
typescript interface react-redux typescript-typings
asked Nov 21 '18 at 9:58


MrMamenMrMamen
508
508
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
You can just use the typeof
type operator to get the type of any constant. You can then use a type alias to give it a name
const ActionCreators = {
foo: (a: string): string => ("foo" + a),
bar: (a: number): string => ("bar" + a),
baz: (a: boolean): number => (a ? 256 : 123)
};
type Props = typeof ActionCreators;
/*
Same as
type Props = {
foo: (a: string) => string;
bar: (a: number) => string;
baz: (a: boolean) => number;
}
*/
While there are subtle differences between interfaces and type aliases in this case they should be equivalent.
Edit
Follow-up question in the comments: How can I change the return type to void for all member function ?
To do this you need to use a mapped type to map the original type to a new type and a conditional type to extract the argument types of the original function:
type ArgumentTypes<T> = T extends (...a: infer A) => any ? A: //Conditional type extracts the argument types
type Props = {
// Mapped type, maps the keys of the original type to a new type
// with the same keys, and with each key being a function with the same argument as the original
// but returning void.
[P in keyof typeof ActionCreators]: (...a: ArgumentTypes<typeof ActionCreators[P]>) => void
}
That was easy. Thanks. I actually also want to change the return value in Props to void. Is that also as trivial?
– MrMamen
Nov 21 '18 at 11:59
@MrMamen not trivial, nu bo that hard either, I'll add it to the answer shortly
– Titian Cernicova-Dragomir
Nov 21 '18 at 12:01
@MrMamen I added the answer to the follow-up, don't forget to upvote ;)
– Titian Cernicova-Dragomir
Nov 21 '18 at 12:05
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53409465%2fextracting-typescript-signatures-from-an-object-into-an-interface%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can just use the typeof
type operator to get the type of any constant. You can then use a type alias to give it a name
const ActionCreators = {
foo: (a: string): string => ("foo" + a),
bar: (a: number): string => ("bar" + a),
baz: (a: boolean): number => (a ? 256 : 123)
};
type Props = typeof ActionCreators;
/*
Same as
type Props = {
foo: (a: string) => string;
bar: (a: number) => string;
baz: (a: boolean) => number;
}
*/
While there are subtle differences between interfaces and type aliases in this case they should be equivalent.
Edit
Follow-up question in the comments: How can I change the return type to void for all member function ?
To do this you need to use a mapped type to map the original type to a new type and a conditional type to extract the argument types of the original function:
type ArgumentTypes<T> = T extends (...a: infer A) => any ? A: //Conditional type extracts the argument types
type Props = {
// Mapped type, maps the keys of the original type to a new type
// with the same keys, and with each key being a function with the same argument as the original
// but returning void.
[P in keyof typeof ActionCreators]: (...a: ArgumentTypes<typeof ActionCreators[P]>) => void
}
That was easy. Thanks. I actually also want to change the return value in Props to void. Is that also as trivial?
– MrMamen
Nov 21 '18 at 11:59
@MrMamen not trivial, nu bo that hard either, I'll add it to the answer shortly
– Titian Cernicova-Dragomir
Nov 21 '18 at 12:01
@MrMamen I added the answer to the follow-up, don't forget to upvote ;)
– Titian Cernicova-Dragomir
Nov 21 '18 at 12:05
add a comment |
You can just use the typeof
type operator to get the type of any constant. You can then use a type alias to give it a name
const ActionCreators = {
foo: (a: string): string => ("foo" + a),
bar: (a: number): string => ("bar" + a),
baz: (a: boolean): number => (a ? 256 : 123)
};
type Props = typeof ActionCreators;
/*
Same as
type Props = {
foo: (a: string) => string;
bar: (a: number) => string;
baz: (a: boolean) => number;
}
*/
While there are subtle differences between interfaces and type aliases in this case they should be equivalent.
Edit
Follow-up question in the comments: How can I change the return type to void for all member function ?
To do this you need to use a mapped type to map the original type to a new type and a conditional type to extract the argument types of the original function:
type ArgumentTypes<T> = T extends (...a: infer A) => any ? A: //Conditional type extracts the argument types
type Props = {
// Mapped type, maps the keys of the original type to a new type
// with the same keys, and with each key being a function with the same argument as the original
// but returning void.
[P in keyof typeof ActionCreators]: (...a: ArgumentTypes<typeof ActionCreators[P]>) => void
}
That was easy. Thanks. I actually also want to change the return value in Props to void. Is that also as trivial?
– MrMamen
Nov 21 '18 at 11:59
@MrMamen not trivial, nu bo that hard either, I'll add it to the answer shortly
– Titian Cernicova-Dragomir
Nov 21 '18 at 12:01
@MrMamen I added the answer to the follow-up, don't forget to upvote ;)
– Titian Cernicova-Dragomir
Nov 21 '18 at 12:05
add a comment |
You can just use the typeof
type operator to get the type of any constant. You can then use a type alias to give it a name
const ActionCreators = {
foo: (a: string): string => ("foo" + a),
bar: (a: number): string => ("bar" + a),
baz: (a: boolean): number => (a ? 256 : 123)
};
type Props = typeof ActionCreators;
/*
Same as
type Props = {
foo: (a: string) => string;
bar: (a: number) => string;
baz: (a: boolean) => number;
}
*/
While there are subtle differences between interfaces and type aliases in this case they should be equivalent.
Edit
Follow-up question in the comments: How can I change the return type to void for all member function ?
To do this you need to use a mapped type to map the original type to a new type and a conditional type to extract the argument types of the original function:
type ArgumentTypes<T> = T extends (...a: infer A) => any ? A: //Conditional type extracts the argument types
type Props = {
// Mapped type, maps the keys of the original type to a new type
// with the same keys, and with each key being a function with the same argument as the original
// but returning void.
[P in keyof typeof ActionCreators]: (...a: ArgumentTypes<typeof ActionCreators[P]>) => void
}
You can just use the typeof
type operator to get the type of any constant. You can then use a type alias to give it a name
const ActionCreators = {
foo: (a: string): string => ("foo" + a),
bar: (a: number): string => ("bar" + a),
baz: (a: boolean): number => (a ? 256 : 123)
};
type Props = typeof ActionCreators;
/*
Same as
type Props = {
foo: (a: string) => string;
bar: (a: number) => string;
baz: (a: boolean) => number;
}
*/
While there are subtle differences between interfaces and type aliases in this case they should be equivalent.
Edit
Follow-up question in the comments: How can I change the return type to void for all member function ?
To do this you need to use a mapped type to map the original type to a new type and a conditional type to extract the argument types of the original function:
type ArgumentTypes<T> = T extends (...a: infer A) => any ? A: //Conditional type extracts the argument types
type Props = {
// Mapped type, maps the keys of the original type to a new type
// with the same keys, and with each key being a function with the same argument as the original
// but returning void.
[P in keyof typeof ActionCreators]: (...a: ArgumentTypes<typeof ActionCreators[P]>) => void
}
edited Nov 21 '18 at 12:10
answered Nov 21 '18 at 10:55


Titian Cernicova-DragomirTitian Cernicova-Dragomir
64k34160
64k34160
That was easy. Thanks. I actually also want to change the return value in Props to void. Is that also as trivial?
– MrMamen
Nov 21 '18 at 11:59
@MrMamen not trivial, nu bo that hard either, I'll add it to the answer shortly
– Titian Cernicova-Dragomir
Nov 21 '18 at 12:01
@MrMamen I added the answer to the follow-up, don't forget to upvote ;)
– Titian Cernicova-Dragomir
Nov 21 '18 at 12:05
add a comment |
That was easy. Thanks. I actually also want to change the return value in Props to void. Is that also as trivial?
– MrMamen
Nov 21 '18 at 11:59
@MrMamen not trivial, nu bo that hard either, I'll add it to the answer shortly
– Titian Cernicova-Dragomir
Nov 21 '18 at 12:01
@MrMamen I added the answer to the follow-up, don't forget to upvote ;)
– Titian Cernicova-Dragomir
Nov 21 '18 at 12:05
That was easy. Thanks. I actually also want to change the return value in Props to void. Is that also as trivial?
– MrMamen
Nov 21 '18 at 11:59
That was easy. Thanks. I actually also want to change the return value in Props to void. Is that also as trivial?
– MrMamen
Nov 21 '18 at 11:59
@MrMamen not trivial, nu bo that hard either, I'll add it to the answer shortly
– Titian Cernicova-Dragomir
Nov 21 '18 at 12:01
@MrMamen not trivial, nu bo that hard either, I'll add it to the answer shortly
– Titian Cernicova-Dragomir
Nov 21 '18 at 12:01
@MrMamen I added the answer to the follow-up, don't forget to upvote ;)
– Titian Cernicova-Dragomir
Nov 21 '18 at 12:05
@MrMamen I added the answer to the follow-up, don't forget to upvote ;)
– Titian Cernicova-Dragomir
Nov 21 '18 at 12:05
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53409465%2fextracting-typescript-signatures-from-an-object-into-an-interface%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown