action-typed
Advanced tools
/** | ||
* Accept a plain object literal where the keys are stings (or enum members) | ||
* and produce a function that can be called with 100% typesafety. | ||
* | ||
* This is done by using Typescripts ability to infer the return types of functions | ||
* combined with the ability to create new types from existing ones (mapped types) | ||
* First, define your app's messages in an Object Literal 'type' | ||
* | ||
* eg: | ||
* | ||
* const messages = { | ||
* SignedIn: (firstname: string, lastname: string) => ({firstname, lastname}), | ||
* Token: (token: string) => token, | ||
* SignOut: () => undefined, | ||
* type Messages = { | ||
* SignedIn: { firstname: string, lastname: string }, | ||
* Token: string, | ||
* SignOut: undefined, | ||
* }; | ||
* | ||
* export const Msg = msgCreator(messages); | ||
* // Now, create an 'action creator' | ||
* export const Msg = createMsg<Messages>(); | ||
* | ||
* Msg("Token", "12345") // OK | ||
* Msg("token", "12345") // error | ||
* Msg("Token", 12345) // error | ||
* // You can also extract a 'TypeMap' so that you can index into your actions | ||
* export type TypeMap = ActionMap<Messages>; | ||
* | ||
*/ | ||
export declare function msgCreator<Obj extends Default>(input: Obj): <Kind extends keyof Obj>(kind: Kind, ...args: Parameters<Obj[Kind]>) => { | ||
type: Kind; | ||
payload: LocalReturnType<Obj[Kind]>; | ||
}; | ||
/** | ||
* Added until Typescript lands better support for | ||
* // And once you have the TypeMap, you can use it's own keys to index it (for use as a type-guard) | ||
* export type Actions = TypeMap[keyof TypeMap]; | ||
* | ||
*/ | ||
export declare function bindCreator<Obj extends Default>(input: Obj): <Kind extends keyof Obj>(kind: Kind) => (...args: Parameters<Obj[Kind]>) => { | ||
type: Kind; | ||
payload: LocalReturnType<Obj[Kind]>; | ||
}; | ||
export default msgCreator; | ||
/** | ||
* Defines the structure of the Object literal | ||
* that's used to create all the inferred types. | ||
* | ||
* eg: | ||
* // ------------------------------------------------------------------------------------------------------------------------ | ||
* | ||
* const messages = { | ||
* Increment: (num = 1) => num | ||
* You can also use an enum to reduce the need for plain strings | ||
* | ||
* enum User { | ||
* SignIn = 'User/SignIn' | ||
* } | ||
* | ||
* type Messages = { | ||
* [User.SignedIn]: { firstname: string, lastname: string }, | ||
* [User.Token]: string, | ||
* [User.SignOut]: undefined, | ||
* }; | ||
* | ||
*/ | ||
declare type Default = { | ||
[key: string]: (...args: any[]) => any; | ||
export declare function createMsg<Obj extends { | ||
[index: string]: any; | ||
}>(): <Key extends keyof Obj>(name: Key, ...args: Obj[Key] extends undefined ? [] : [Obj[Key]]) => { | ||
type: Key; | ||
payload: Obj[Key]; | ||
} | { | ||
type: Key; | ||
payload?: undefined; | ||
}; | ||
/** | ||
* Use this to create a union of all possible action | ||
* types in the form {type: string, payload: inferred}. | ||
* | ||
* You can then use this union type with something | ||
* like a switch statement to narrow the type-checking | ||
* Use this to create a index of all your object shapes | ||
* | ||
* Eg: | ||
* // You can also extract a 'TypeMap' so that you can index into your actions | ||
* export type TypeMap = ActionMap<Messages>; | ||
* | ||
* type AllActions = ActionHandler<typeof messages> | ||
* // And once you have the TypeMap, you can use it's own keys to index it (for use as a type-guard) | ||
* export type Actions = TypeMap[keyof TypeMap]; | ||
* | ||
*/ | ||
export declare type ActionHandler<T extends { | ||
[key: string]: {}; | ||
}> = ActionTypeMap<T>[keyof ActionTypeMap<T>]; | ||
/** | ||
* Converts the `messages` structure to type + payload, where type | ||
* is the original Object key, and 'payload' is the inferred return type | ||
*/ | ||
export declare type ActionTypeMap<T extends { | ||
[key: string]: {}; | ||
export declare type ActionMap<M extends { | ||
[index: string]: any; | ||
}> = { | ||
[K in keyof T]: { | ||
type: K; | ||
payload: LocalReturnType<T[K]>; | ||
[Key in keyof M]: M[Key] extends undefined ? { | ||
type: Key; | ||
} : { | ||
type: Key; | ||
payload: M[Key]; | ||
}; | ||
}; | ||
/** | ||
* This type will extract the inferred return type of a | ||
* given function (T) | ||
*/ | ||
export declare type LocalReturnType<T> = T extends (...args: any[]) => infer R ? R : never; | ||
/** | ||
* A helper to convert a map of names & action creators | ||
* into a map of (...params) => void - this is useful | ||
* when using mapDispatchToProps from redux | ||
* | ||
* eg: | ||
* | ||
* export const messages = { | ||
* Increment: (num = 1) => num, | ||
* Decrement: (num = 1) => num, | ||
* }; | ||
* | ||
* export type AsFn = AsVoidReturn<typeof messages>; | ||
* | ||
* AsFn["Increment"] // (number | undefined) => void | ||
*/ | ||
export declare type AsVoidReturn<T extends { | ||
[key: string]: (...args: any[]) => any; | ||
} = {}> = { | ||
[K in keyof T]: (...params: Parameters<T[K]>) => void; | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
* Accept a plain object literal where the keys are stings (or enum members) | ||
* and produce a function that can be called with 100% typesafety. | ||
* | ||
* This is done by using Typescripts ability to infer the return types of functions | ||
* combined with the ability to create new types from existing ones (mapped types) | ||
* First, define your app's messages in an Object Literal 'type' | ||
* | ||
* eg: | ||
* | ||
* const messages = { | ||
* SignedIn: (firstname: string, lastname: string) => ({firstname, lastname}), | ||
* Token: (token: string) => token, | ||
* SignOut: () => undefined, | ||
* type Messages = { | ||
* SignedIn: { firstname: string, lastname: string }, | ||
* Token: string, | ||
* SignOut: undefined, | ||
* }; | ||
* | ||
* export const Msg = msgCreator(messages); | ||
* // Now, create an 'action creator' | ||
* export const Msg = createMsg<Messages>(); | ||
* | ||
* Msg("Token", "12345") // OK | ||
* Msg("token", "12345") // error | ||
* Msg("Token", 12345) // error | ||
* // You can also extract a 'TypeMap' so that you can index into your actions | ||
* export type TypeMap = ActionMap<Messages>; | ||
* | ||
* // And once you have the TypeMap, you can use it's own keys to index it (for use as a type-guard) | ||
* export type Actions = TypeMap[keyof TypeMap]; | ||
* | ||
* | ||
* // ------------------------------------------------------------------------------------------------------------------------ | ||
* | ||
* You can also use an enum to reduce the need for plain strings | ||
* | ||
* enum User { | ||
* SignIn = 'User/SignIn' | ||
* } | ||
* | ||
* type Messages = { | ||
* [User.SignedIn]: { firstname: string, lastname: string }, | ||
* [User.Token]: string, | ||
* [User.SignOut]: undefined, | ||
* }; | ||
* | ||
*/ | ||
function msgCreator(input) { | ||
return function Msg(kind) { | ||
function createMsg() { | ||
return function (name) { | ||
var args = []; | ||
@@ -31,37 +44,9 @@ for (var _i = 1; _i < arguments.length; _i++) { | ||
} | ||
var output = input[kind].apply(null, args); | ||
if (output === undefined) { | ||
return { type: kind, payload: undefined }; | ||
if (args.length > 0) { | ||
return { type: name, payload: args[0] }; | ||
} | ||
return { | ||
type: kind, | ||
payload: output, | ||
}; | ||
return { type: name }; | ||
}; | ||
} | ||
exports.msgCreator = msgCreator; | ||
/** | ||
* Added until Typescript lands better support for | ||
* | ||
*/ | ||
function bindCreator(input) { | ||
return function MsgBind(kind) { | ||
return function Msg() { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
var output = input[kind].apply(null, args); | ||
if (output === undefined) { | ||
return { type: kind, payload: undefined }; | ||
} | ||
return { | ||
type: kind, | ||
payload: output, | ||
}; | ||
}; | ||
}; | ||
} | ||
exports.bindCreator = bindCreator; | ||
exports.default = msgCreator; | ||
exports.createMsg = createMsg; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "action-typed", | ||
"version": "1.0.10", | ||
"version": "2.0.0", | ||
"description": "Better type *safety*, with less actual *typing* for Redux actions", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
8143
-20.27%115
-30.72%1
Infinity%