Redux-toolkit: Export Types

Created on 10 Dec 2019  路  11Comments  路  Source: reduxjs/redux-toolkit

Would it be possible to export the types used in this project. i want to extend some functionallity and need to copy&paste many of them to my code, so i can access them.

i.e: CaseReducerActions, RestrictCaseReducerDefinitionsToMatchReducerAndPrepare, ...

Most helpful comment

Hi @wuifdesign, some of these types are deliberately not exported, as they are really just useful internally and we might replace them with simpler types as we find better solutions.
As soon as we export an internal type, essentially we have to support it forever and can never change it to not break things for people.
Especially RestrictCaseReducerDefinitionsToMatchReducerAndPrepare is a type that I am expecting to remove soon using the technique displayed in this playground.

Exporting CaseReducerActions would also require us to export SliceCaseReducerDefinitions, which relies on PayloadActions and some of these might also become obsolete using the same technique.

Could you please explain with a few code snippets what you are trying to do?
Maybe I can help you around your problems with only our exported types - and maybe that'll even lead to something we can add to our TypeScript documentation afterwards :)

PS: using those types should not be necessary for you and should even be avoided, as overspecifying your types instead of using inteference will erase useful type information and make your types overall worse in the end.

All 11 comments

Hi @wuifdesign, some of these types are deliberately not exported, as they are really just useful internally and we might replace them with simpler types as we find better solutions.
As soon as we export an internal type, essentially we have to support it forever and can never change it to not break things for people.
Especially RestrictCaseReducerDefinitionsToMatchReducerAndPrepare is a type that I am expecting to remove soon using the technique displayed in this playground.

Exporting CaseReducerActions would also require us to export SliceCaseReducerDefinitions, which relies on PayloadActions and some of these might also become obsolete using the same technique.

Could you please explain with a few code snippets what you are trying to do?
Maybe I can help you around your problems with only our exported types - and maybe that'll even lead to something we can add to our TypeScript documentation afterwards :)

PS: using those types should not be necessary for you and should even be avoided, as overspecifying your types instead of using inteference will erase useful type information and make your types overall worse in the end.

i wont to extend the createSlice a bit. something like that (only as example, i want to add thunks or sagas or something else):

export function createAdvancedSlice<State, CaseReducers extends SliceCaseReducerDefinitions<State, any>>(
  options: CreateSliceOptions<State, CaseReducers> & RestrictCaseReducerDefinitionsToMatchReducerAndPrepare<State, CaseReducers>,
  advancedOptions: any = {},
) {
  const { test } = advancedOptions;
  const slice: Slice<State, CaseReducers> = createSlice(options);

  return {
    ...slice,
    test,
  };
}

and to keep typehinting for options i need this types.

Hm. I understand you use case.

Of course, we could do something like exporting those types under a different name like __WARNING_UNSUPPORTED_SliceCaseReducerDefinitions, but in the end that would not change the underlying problem: we will change these types (definitely their Generics Signature and possibly even their name) and every time we do that it will hurt you and everyone else using these types.

I have an alternative suggestion that might hurt a lot less in the future: What do you think about wrapping the Return Type of createSlice?

That would even be composable with multiple ways of extending it:

import {createSlice, Slice} from '@reduxjs/toolkit';


export function enhanceSlice<S extends Slice<any,any>>(
  slice: S,
  advancedOptions: any = {},
) {
  const { test } = advancedOptions;

  return {
    ...slice,
    test,
  };
}


const x = enhanceSlice(createSlice({
  name: "test",
  initialState: 0,
  reducers: {}
}), {
  test: "asd"
})

it would be ok if the types change. i know if i implement another library like that an update can effect my implementation. it is ok, if the options change.

It would be better to have types comming from the libary as copying it to my code, as i copy it, i will not get a type error even if the options changed and the ones i currently provide didn't match the current ones. if i copy them i have to check them on each update if they match the current from the library.

Phew. I'm pretty torn here.

@markerikson, what are your thoughts on exporting a copy of those types as __INTERNAL_UNSTABLE_RestrictCaseReducerDefinitionsToMatchReducerAndPrepare etc.?

I would really rather not export those.

Couldn't you do some kind of ReturnType<typeof createSlice> / Parameters<typeof createSlice> thing to extract the types as needed?

That won't work, as the parameters are dependent on Generics - ReturnType always returns a "flat" type with all "generic-ity" removed.

So, @wuifdesign, as you see, we both aren't feeling good on this one.
This is something we might reconsider after we reach a point where we can't think of any features to be added and thus assuming that those typings are stable, but I think we're not going to export those types for now.

You might - for now - actually be better of just copying those types into your code base, because the shape of those objects is not going to change anytime soon - just the types describing that shape. So if you copy the types out, you probably won't get a lot less conflicts than if you were to reference our types.

Although I'd again suggest to go for a "wrapping the result" style instead of a "wrapping the function" style, as I suggested in https://github.com/reduxjs/redux-toolkit/issues/276#issuecomment-564625147 - that won't require any knowledge of our internal types at all.

Yeah. Given that this isn't something we plan to do at the moment, I'll close this.

Hey @wuifdesign - the type refactor is through and we now felt confident to export some of those types.

here's how to use them - I hope it helps you!

@phryneas thx, i already saw it, and i will try it after holidays

Was this page helpful?
0 / 5 - 0 ratings