Reputation: 898
Let's say there is an interface that restricts what kind of keys or values can be used in an object. For example, an interface like that could be used for storing some calculations.
interface CheckNumberMethods {
[key: string]: (n: number) => boolean
}
So while creating an actual object with some methods, I would apply that interface to have the IDE check for type mismatches.
const myMethods:CheckNumberMethods = {
greaterThanFive: (n: number) => n > 5,
isEven: (n: number) => n % 2 === 0,
}
But now the object is stuck with the type MyMethodsType
. While I want the type to represent the actual object I've created. In this example, the object's type should look like this:
{
greaterThanFive: (n: number) => boolean;
isEven: (n: number) => boolean;
}
Of course, that this is natural behavior, but is there a way to have type checking while creating the object, but to keep the original object's type for "outside" usage?
In this example simply extending the interface and applying the extended one to the object would work just fine, but on a bigger scale or with more complex types it is troublesome.
Upvotes: 1
Views: 1000
Reputation: 33091
In order to infer exact properties and make object assignable to CheckNumberMethods
interface, you should create a function with appropriate constraints.
Example:
interface CheckNumberMethods {
[key: string]: (n: number) => boolean
}
const myMethods = {
greaterThanFive: (n: number) => n > 5,
isEven: (n: number) => n % 2 === 0,
}
const handle = <Obj extends CheckNumberMethods>(obj: Obj) => obj
// {
// greaterThanFive: (n: number) => boolean;
// isEven: (n: number) => boolean;
// }
const result = handle(myMethods)
I have removed explicit type CheckNumberMethods
from myMethods
because it affects return type of handle
function.
Hence, you are able to infer exact properties only with extra function.
Upvotes: 2