user13203487
user13203487

Reputation:

Generic interface inferring type from object property

I've got an interface I with the goal of making sure that the property type of val is the same as the return type of fn.

The type in question is restricted to string or number.

interface I<T extends string | number> {
  val: T;
  fn: () => T;
}

const x1: I<string> = {
  val: "hello",
  fn: () => "world",
};

const x2: I<number> = {
  val: 3,
  fn: () => 4,
};

Is it somehow possible to not having to explicitly set T and rather infer it? So that I could just do:

// accepted
const x1: I = {
  val: "hello",
  fn: () => "world",
};

// accepted
const x2: I = {
  val: 3,
  fn: () => 4,
};

// rejected
const x3: I = {
  val: "hello",
  fn: () => 4,
};

// rejected
const x4: I = {
  val: 3,
  fn: () => "world",
};

Upvotes: 1

Views: 66

Answers (1)

Tanek Loc
Tanek Loc

Reputation: 361

As far as I know, it is not possible for TS to infer the type for your example. However, there is a way to achieve similar effects using a helper function:

function make<T extends string|number>(input: I<T>) {
  return input;
}

// accepted
const x1 = make({
  val: "hello",
  fn: () => "world",
});

// accepted
const x2 = make({
  val: 3,
  fn: () => 4,
});

// rejected
const x3 = make({
  val: "hello",
  fn: () => 4,
});

// rejected
const x4 = make({
  val: 3,
  fn: () => "world",
});

Playground link

Upvotes: 0

Related Questions