Reputation: 3496
I have a function that creates functions.
for example
function createFunc<T>()
{
return (params: T) => params /* do stuff here */;
}
and use it for type checking. So, for example, I can create a function with this signature
login = createFunc<{username:string,password:string}>();
Now it's checking login method inputs to be {username:string,password:string}
But how can I do this for an empty object?
When I pass {}
its allow to put anything in the input, I want to check that input must be empty object only.
Upvotes: 2
Views: 1550
Reputation: 249636
Typescript will not trigger excess property checks for {}
. So if you want to forbid properties with extra properties you could treat this case explicitly using a conditional type:
function createFunc<T>():
keyof T extends never ?
(params: Record<string, never>) => {} :
(params: T) => T
function createFunc()
{
return (params: any) => params /* do stuff here */;
}
const empty = createFunc<{ }>();
empty({
password: "",
username: ""
})
You should be careful about relying to much on excess property checks, they are only triggered when you assign an object literal directly to the parameter. This for example passes:
const login = createFunc<{ username: string, password: string }>();
const p = {
password: "",
password2: "",
username: ""
}
login(p) // ok no EPC triggered
If you want to tighten this up you can use an extra type parameter to capture the actual parameter type passed in and force any excess properties to be of type never
:
function createFunc<T>() {
return <U extends T>(params: U & Record<Exclude<keyof U, keyof T>, never>): U => params /* do stuff here */;
}
const empty = createFunc<{}>();
empty({
password: "",
username: ""
}) // err
const login = createFunc<{ username: string, password: string }>();
const p = {
password: "",
password2: "",
username: ""
}
login(p) // err
login({
password: "",
username: ""
}) // ok
Upvotes: 4