Home > Mobile >  Dynamic types in typescript
Dynamic types in typescript

Time:01-05

How would one define the return type of the fn function below?

const fn = (propName: string) => {
  return { [propName]: () => true }
}
const x = fn('customProp')
console.log(x.customProp)

e.g.

type FN = (propName: string)=> {
  [propName]: ()=>true
}

CodePudding user response:

As long as propName is a string, you can do:

type FN_return = {[propName: string]: ()=>true};

CodePudding user response:

If you want to be safe and are ok with being a little verbose, then use TypeScript Generics:

const fn = <T extends string>(propName: T): { [_ in T]: () => true } => {
  return { [propName]: () => true } as any; // a cast is sadly required for generic return types
}
const x = fn('customProp')
console.log(x.customProp) // ✅ works fine
x.notHere // ❌ compile error

Also, this will automatically support if you are passing in a generic string type with the unsafe counterpart that the other answer used.

const y = fn("foo" as string); // same as Record<string, () => true>
y.foo; // compiles but is valid
y.asdf; // compiles but is undefined

If you wanted to be extremely safe, then you could actually change your return type when someone passes in a string (not exact string type) using conditional types to show it could be undefined:

const fn = <T extends string>(propName: T): { [_ in T]: Exclude<undefined | (() => true), string extends T ? never : undefined> } => {
  return { [propName]: () => true } as any;
}
const x = fn("hello"); // { hello: () => true; }
x.asdf // ❌ compile error
const y = fn("hello" as string); // { [x: string]: (() => true) | undefined; }
y.foo // (() => true) | undefined
y.hello // (() => true) | undefined
  •  Tags:  
  • Related