conditional types using generics in react component

Note: I have a working solution for this problem, but I am hoping somebody may be able to show me a more efficient and compact way to implement it.

Problem:

I have a react component like so:

function Component({ idIdentifier = "id", nameIdentifier = "name", persons }) { // render

the idea is that the persons prop should be an array of object(s) that match the identifiers specified in the idIdentifier and nameIdentifier props, for example using default prop values it should look like:

persons = [ { id: "1", name: "Joe" } ]

I want to make this component more powerful by adding type specification using TypeScript. I need the specification to be sophisticated enough so it can flag errors when the following occurs:

when using Component type of persons prop being passed in does not match specification when:

  • idIdentifier and nameIdentifier props not passed, default values used
  • Custom value for idIdentifier prop passed and
    nameIdentifier prop not passed, default value used for latter
  • Custom value for nameIdentifier prop passed and
    idIdentifier prop not passed, default value used for latter
  • Custom value for both nameIdentifier and
    idIdentifier props passed

Below is my solution:

const ID = 'id'
const NAME = 'name'

type Id = typeof ID
type Name = typeof NAME

type Persons<T1 extends string, T2 extends string> = { [key in (T1 | T2)]: string }[]

type VariableProps<T1, T2> = {
  idIdentifier?: T1
  nameIdentifier?: T2
}

type DefaultProps = {
  persons: Persons<Id, Name>
} & VariableProps<Id, Name>

type PropsWithName<T extends string> = {
  idIdentifier?: T
  nameIdentifier: Id
  persons: Persons<Id, T>
}

type PropsWithId<T extends string> = {
  idIdentifier: T
  nameIdentifier?: Name
  persons: Persons<T, Name>
}

type PropsWithIdAndName<T1 extends string, T2 extends string> = {
  persons: Persons<T1, T2>
} & Required<VariableProps<T1, T2>>

type AllProps<T1 extends string, T2 extends string> = (DefaultProps | PropsWithName<T1> | PropsWithId<T2> | PropsWithIdAndName<T1, T2>)

function Component<T1 extends string, T2 extends string>({ idIdentifier = ID, nameIdentifier = NAME, persons }: AllProps<T1, T2>) { // render

My solution does work and it will give me the warnings I need under all scenarios when there is a mismatch, but I wondered if my code could be more compact, the real world Component has more moving parts and this approach has doubled the length of the file.

Any feedback greatly appreciated, thanks.