2

I'm trying to create a type to express the following constraint:

// Valid
{
  "foo": "foo"
}

// Valid
{
  "bar": "bar"
}

// Not valid
{
  "foo": "bar"
}

I think I should be able to do this with mapped types:

type KeyValueSameDict = {
  [key in string]: key
};

However, this simply infers the type Record<string, string>. I also think I could do this if I knew the keys ahead of time:

type KeyValueSameDictKeys = "foo" | "bar";

type KeyValueSameDict = {
  [v in KeyValueSameDictKeys]?: v;
};

However, I would like a way to not have to do that.

Is what I'm trying to do possible?

1 Answer 1

1

Ah, so we can do this if we split out the inference to an identity function:

type KeyValueSameDict<Keys extends string> = {
  [v in Keys]?: v;
};

function inferGeneric<T extends string>(t: KeyValueSameDict<T>) {
  return t;
}

const foo = inferGeneric({ foo: 'foo', bar: 'bar' } as const);
Sign up to request clarification or add additional context in comments.

3 Comments

I think this is better than my answer. It works for objects with more than one key
Making the key/value pairs was not optional in the question @Tomas Reimers.
@sno2 apologies if I wasn't clear - what do you mean it wasn't possible for it to be optional?

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.