Reputation: 4255
Let's say I have this function (ignore the purpose of it, it's just a basic example):
const doSomething = (object1, object2) => {
return { ...object1, ...object2 }
}
If object2
needs to be the same type as object
, how do I write the type definition?
For example,
interface DefaultObject {
foo: number,
other?: string
}
const object1: DefaultObject = {
foo: 1
}
// :::::::::::::::::::::::::::::::::::
const object2 = {
other: "something"
}
doSomething(object1, object2)
// this should error as object2 does not contain the required 'foo' key/value pair
// :::::::::::::::::::::::::::::::::::
const object3 = {
foo: "1"
}
doSomething(object1, object3)
// this should error as object3's 'foo' value is not a number
// :::::::::::::::::::::::::::::::::::
const object4 = {
foo: 2,
bar: 2
}
doSomething(object1, object4)
// this should error as object2 contains an extra 'bar' key/value pair
// :::::::::::::::::::::::::::::::::::
const object5 = {
foo: 2
}
doSomething(object1, object5)
// this should pass as both objects have the same DefaultObject type
// :::::::::::::::::::::::::::::::::::
Upvotes: 1
Views: 832
Reputation: 250316
You can add a generic type parameter to the function ad use it for both object1
and object2
const doSomething = <T,>(object1: T, object2: T) => { // comma for tsx files
return { ...object1, ...object2 }
}
Edit
Your 4th test works, because a type with extra properties is a subtype of DefaultObject
so it will be assignable to where a DefaultObject
reference is expected.
You can use conditional types to force an error if any extra keys are present on the second parameter:
const doSomething = <T, U extends T>(object1: T, object2: U & (keyof U extends keyof T ? {} : "No etxra keys")) => { // comma for tsx files
return { ...object1, ...object2 }
}
Upvotes: 1