3

How do I declare generic type for a function created dynamically?

type FooType = {
  username: string;
}

type BarType = {
  age: number;
}

interface DataStore {
  foo: FooType;
  bar: BarType;
}

const getDataStore = () => ({
  foo: { username: 'Tera' },
  bar: { age: 24 },
})

const generateFunction = <T, S extends keyof DataStore>(slice: S) => {
  type DataSlice = DataStore[S];

  return (selector: (store: DataSlice) => T) => selector(getDataStore()?.[slice]);
}

How do I use T in useFoo and pass generateFunction?

const useFoo = generateFunction('foo');

Expected usage of useFoo

type UserName = string;

const userName = useFoo<UserName>((foo: FooType) => foo.userName);
3
  • 2
    Please provide reproducible example. User, getDataStore, FooType,BarType are not defined Commented Sep 8, 2022 at 7:28
  • 1
    Are you looking for generateFunction<T>('foo'); where T is your desired return type for the generated function? Commented Sep 8, 2022 at 7:42
  • @MichaelBrenndoerfer yes, but how do I declare T for useFoo in this case? Commented Sep 8, 2022 at 7:43

1 Answer 1

5

You're looking for generic anonymous functions (see this SO answer).

const generateFunction = <S extends keyof DataStore>(slice: S) => {
  type DataSlice = DataStore[S];

  return <T,>(selector: (store: DataSlice) => T) => selector(getDataStore()?.[slice]);
}

Note that the T generic is now associated with the returned function, instead of generateFunction itself. As written in your question, generateFunction is a generic function that takes two generic parameters T and S that are known when calling the function. Instead, you want generateFunction to take a single generic parameter S that's known when calling, and have it return a function with a single generic parameter T that's only known when the returned function is called.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.