It doesn't seem possible to achieve your desired outcome in the exact way you want. This would necessitate the use of a generic, leading to the common error message: "Type '{foo: boolean}' is not assignable to type 'T'...'T' could be instantiated with an arbitrary type which could be unrelated to '{foo: boolean}'." You can see an example of this error here.
However, if you transfer your {foo: boolean}
from the function return to the constant's type annotation, you can avoid encountering that problem:
type MyFunc<T> = (param: T) => T;
const myFunc: MyFunc<{foo: boolean}> = (param) => {
// Move here −−−−−−−^^^^^^^^^^^^^^^^− instead of ^
return {foo: true};
};
Playground link
In a subsequent edit after this answer was published, you mentioned wanting to avoid extra properties on the returned object (originally it was not even an object). This raises a completely different question and should be addressed separately (if it hasn't already been). Note that excess property checks are applied very selectively in TypeScript. I don't have precise details, but the types must be closely defined for excess property checks to take place.
To illustrate how limited their application is, they apply in this scenario (link):
const example = (): {foo: boolean } => {
return {foo: true, bar: false};
// ^− Type '{ foo: true; bar: boolean; }' is not assignable to type '{ foo: boolean; }'.
// Object literal may only specify known properties, and 'bar' does not exist in type '{ foo: boolean; }'.
};
...but not in this case (link):
type ExampleFunction = () => {foo: boolean };
const example: ExampleFunction = () => {
return {foo: true, bar: false};
// No error here −−^
};
It's unlikely that these checks will be applicable to your specific situation, prompting the need for a separate inquiry from the original one that was asked and answered.