or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

action-creators.mdaction-helpers.mdindex.mdtype-helpers.md

type-helpers.mddocs/

0

# Type Helpers

1

2

Complete TypeScript type definitions and interfaces for building type-safe Redux applications with action creators, reducers, and state management utilities.

3

4

## Capabilities

5

6

### Core Types

7

8

Basic type definitions that form the foundation of the type system.

9

10

```typescript { .api }

11

/**

12

* Type representing action type constants (string literals)

13

*/

14

type TypeConstant = string;

15

16

/**

17

* Generic action interface with type property

18

*/

19

interface Action<TType extends TypeConstant = TypeConstant> {

20

type: TType;

21

}

22

23

/**

24

* Generic action creator function type

25

*/

26

type ActionCreator<TAction extends Action = Action> = (

27

...args: any[]

28

) => TAction;

29

30

/**

31

* Generic reducer function type

32

*/

33

type Reducer<TState, TAction extends Action> = (

34

state: TState | undefined,

35

action: TAction

36

) => TState;

37

```

38

39

### Action Types

40

41

Specialized action types for different payload and meta combinations.

42

43

```typescript { .api }

44

/**

45

* Action without payload (type only)

46

*/

47

type EmptyAction<TType extends TypeConstant> = Action<TType>;

48

49

/**

50

* Action with payload property

51

*/

52

interface PayloadAction<TType extends TypeConstant, TPayload> extends Action<TType> {

53

payload: TPayload;

54

}

55

56

/**

57

* Action with both payload and meta properties

58

*/

59

interface PayloadMetaAction<TType extends TypeConstant, TPayload, TMeta>

60

extends PayloadAction<TType, TPayload> {

61

meta: TMeta;

62

}

63

```

64

65

### Action Creator Types

66

67

Specialized action creator types corresponding to different action types.

68

69

```typescript { .api }

70

/**

71

* Action creator that produces EmptyAction

72

*/

73

type EmptyActionCreator<TType extends TypeConstant> = ActionCreator<EmptyAction<TType>>;

74

75

/**

76

* Action creator that produces PayloadAction

77

*/

78

type PayloadActionCreator<TType extends TypeConstant, TPayload> =

79

ActionCreator<PayloadAction<TType, TPayload>>;

80

81

/**

82

* Action creator that produces PayloadMetaAction

83

*/

84

type PayloadMetaActionCreator<TType extends TypeConstant, TPayload, TMeta> =

85

ActionCreator<PayloadMetaAction<TType, TPayload, TMeta>>;

86

```

87

88

### Type Metadata Interface

89

90

Interface for action creators with type metadata support.

91

92

```typescript { .api }

93

/**

94

* Interface representing type getter on action creator instance

95

*/

96

interface ActionCreatorTypeMetadata<TType extends TypeConstant> {

97

getType?(): TType;

98

}

99

```

100

101

### Utility Types

102

103

Advanced utility types for type inference and manipulation.

104

105

```typescript { .api }

106

/**

107

* Infers action union type from action creator or action creator map

108

*/

109

type ActionType<TActionCreatorOrMap extends any> =

110

TActionCreatorOrMap extends ActionCreator<TypeConstant>

111

? ReturnType<TActionCreatorOrMap>

112

: TActionCreatorOrMap extends Record<any, any>

113

? { [K in keyof TActionCreatorOrMap]: ActionType<TActionCreatorOrMap[K]> }[keyof TActionCreatorOrMap]

114

: never;

115

116

/**

117

* Infers state object type from reducer or reducer map

118

*/

119

type StateType<TReducerOrMap extends any> =

120

TReducerOrMap extends Reducer<any, any>

121

? ReturnType<TReducerOrMap>

122

: TReducerOrMap extends Record<any, any>

123

? { [K in keyof TReducerOrMap]: StateType<TReducerOrMap[K]> }

124

: never;

125

```

126

127

### Builder Types

128

129

Types used internally by action creator builders.

130

131

```typescript { .api }

132

/**

133

* Action builder type for createAction results

134

*/

135

type ActionBuilder<TType extends TypeConstant, TPayload = undefined, TMeta = undefined> =

136

TPayload extends undefined

137

? TMeta extends undefined

138

? EmptyAction<TType>

139

: never

140

: TMeta extends undefined

141

? PayloadAction<TType, TPayload>

142

: PayloadMetaAction<TType, TPayload, TMeta>;

143

144

/**

145

* Action creator builder interface for createAction

146

*/

147

interface ActionCreatorBuilder<TType extends TypeConstant, TPayload = undefined, TMeta = undefined> {

148

(): TPayload extends undefined

149

? TMeta extends undefined

150

? () => EmptyAction<TType>

151

: never

152

: never;

153

154

<P>(): TMeta extends undefined

155

? (payload: P) => PayloadAction<TType, P>

156

: never;

157

158

<P, M>(): (payload: P, meta: M) => PayloadMetaAction<TType, P, M>;

159

160

map<R, P>(

161

fn: (payload: P) => R

162

): TPayload extends undefined

163

? ActionCreatorBuilder<TType, R, TMeta>

164

: never;

165

}

166

167

/**

168

* Async action creator builder for createAsyncAction

169

*/

170

interface AsyncActionCreatorBuilder<

171

TRequestType extends TypeConstant,

172

TSuccessType extends TypeConstant,

173

TFailureType extends TypeConstant,

174

TCancelType extends TypeConstant = never

175

> {

176

request: ActionCreatorBuilder<TRequestType>;

177

success: ActionCreatorBuilder<TSuccessType>;

178

failure: ActionCreatorBuilder<TFailureType>;

179

cancel: TCancelType extends TypeConstant

180

? ActionCreatorBuilder<TCancelType>

181

: never;

182

}

183

```

184

185

### Module Augmentation Interface

186

187

Interface for augmenting the library with custom types.

188

189

```typescript { .api }

190

/**

191

* Interface for module augmentation - extend this in your app

192

* @example

193

* ```

194

* declare module 'typesafe-actions' {

195

* export type RootAction = ActionType<typeof import('./root-action').default>;

196

* export interface Types {

197

* RootAction: RootAction;

198

* }

199

* }

200

* ```

201

*/

202

interface Types {

203

RootAction: Action;

204

}

205

```

206

207

## Usage Examples

208

209

### Basic Type Usage

210

211

```typescript

212

import type {

213

Action,

214

ActionCreator,

215

PayloadAction,

216

EmptyAction

217

} from "typesafe-actions";

218

219

// Define action types

220

type IncrementAction = PayloadAction<'INCREMENT', number>;

221

type DecrementAction = EmptyAction<'DECREMENT'>;

222

type CounterAction = IncrementAction | DecrementAction;

223

224

// Define action creators with proper typing

225

const increment: ActionCreator<IncrementAction> = (payload: number) => ({

226

type: 'INCREMENT',

227

payload,

228

});

229

230

const decrement: ActionCreator<DecrementAction> = () => ({

231

type: 'DECREMENT',

232

});

233

```

234

235

### ActionType and StateType Usage

236

237

```typescript

238

import { createAction, createReducer } from "typesafe-actions";

239

import type { ActionType, StateType } from "typesafe-actions";

240

241

// Create action creators

242

const counterActions = {

243

increment: createAction('INCREMENT')<number>(),

244

decrement: createAction('DECREMENT')(),

245

reset: createAction('RESET')(),

246

};

247

248

// Infer action union type

249

type CounterAction = ActionType<typeof counterActions>;

250

// Result: ReturnType<typeof increment> | ReturnType<typeof decrement> | ReturnType<typeof reset>

251

252

// Create reducers

253

const rootReducer = {

254

counter: createReducer({ count: 0 })

255

.handleAction(counterActions.increment, (state, action) => ({

256

count: state.count + action.payload,

257

}))

258

.handleAction(counterActions.decrement, (state) => ({

259

count: state.count - 1,

260

}))

261

.handleAction(counterActions.reset, () => ({ count: 0 })),

262

263

user: createReducer({ name: '', email: '' })

264

.handleAction(setUser, (state, action) => action.payload),

265

};

266

267

// Infer root state type

268

type RootState = StateType<typeof rootReducer>;

269

// Result: { counter: { count: number }, user: { name: string, email: string } }

270

```

271

272

### Module Augmentation

273

274

```typescript

275

// In your application's type definitions file

276

import { ActionType } from 'typesafe-actions';

277

278

declare module 'typesafe-actions' {

279

interface Types {

280

RootAction: ActionType<typeof rootActions>;

281

}

282

}

283

284

// Now you can use RootAction throughout your app

285

import type { RootAction } from 'typesafe-actions';

286

287

function handleAction(action: RootAction) {

288

// action is typed as your app's root action union

289

}

290

```

291

292

### Advanced Generic Usage

293

294

```typescript

295

import type {

296

ActionCreatorBuilder,

297

AsyncActionCreatorBuilder,

298

ActionCreatorTypeMetadata

299

} from "typesafe-actions";

300

301

// Generic action creator factory

302

function createTypedAction<T extends string>(type: T) {

303

return <P = undefined, M = undefined>(): ActionCreatorBuilder<T, P, M> => {

304

// Implementation would go here

305

return {} as ActionCreatorBuilder<T, P, M>;

306

};

307

}

308

309

// Generic async action factory

310

function createTypedAsyncAction<

311

R extends string,

312

S extends string,

313

F extends string

314

>(requestType: R, successType: S, failureType: F) {

315

return <RP = undefined, SP = undefined, FP = undefined>():

316

AsyncActionCreatorBuilder<R, S, F> => {

317

// Implementation would go here

318

return {} as AsyncActionCreatorBuilder<R, S, F>;

319

};

320

}

321

322

// Usage with full type inference

323

const typedAction = createTypedAction('TYPED_ACTION')<string, number>();

324

const result = typedAction('payload', 42);

325

// result is typed as PayloadMetaAction<'TYPED_ACTION', string, number>

326

```

327

328

### Type Guards and Narrowing

329

330

```typescript

331

import type { Action, PayloadAction, EmptyAction } from "typesafe-actions";

332

333

// Custom type guards

334

function isPayloadAction<T extends string, P>(

335

action: Action,

336

type: T

337

): action is PayloadAction<T, P> {

338

return action.type === type && 'payload' in action;

339

}

340

341

function isEmptyAction<T extends string>(

342

action: Action,

343

type: T

344

): action is EmptyAction<T> {

345

return action.type === type && !('payload' in action);

346

}

347

348

// Usage in reducers

349

function counterReducer(state = { count: 0 }, action: Action) {

350

if (isPayloadAction<'INCREMENT', number>(action, 'INCREMENT')) {

351

// TypeScript knows action.payload is number

352

return { count: state.count + action.payload };

353

}

354

355

if (isEmptyAction(action, 'DECREMENT')) {

356

// TypeScript knows action has no payload

357

return { count: state.count - 1 };

358

}

359

360

return state;

361

}

362

```

363

364

## Internal Utility Types

365

366

These types are used internally by the library but may be useful for advanced usage:

367

368

```typescript { .api }

369

/**

370

* Internal type for resolving types - ensures proper type resolution in action creators

371

*/

372

type ResolveType<T> = T extends (...args: any[]) => any ? ReturnType<T> : T;

373

374

/**

375

* Internal utility for excluding never types from unions

376

*/

377

type ExcludeNever<T> = T extends never ? never : T;

378

```