2

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.

1 Answer 1

4

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.