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
