Jake
Jake

Reputation: 4255

Typescript function definition to ensure second parameter is same type as first parameter

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

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

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 }
}

Playground link

Upvotes: 1

Related Questions