0

Typescript newbie here. I've searched everywhere but can't seem to find an answer.

How do I define the structure that would make this code valid. It's some sort of function with a property:

const theThing = createThing(7, 2);
theThing(); // returns a whole number between 1 and 22
theThing.toStringProp();
Eyal Cinamon
  • 939
  • 5
  • 16
  • 1
    The question is "how to implement a callable interface with additional methods", *possibly* with an additional question of "how to restrict the return type of the callable portion to a number between 1 and 22". – Sean Vieira Mar 04 '18 at 17:59

1 Answers1

3

Callables are interfaces with "bare" or unnamed method signatures:

type ValidNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;

interface Thing {
  (): ValidNumber
  toStringProp(): string
}

Constructing them is not entirely type-safe, so it's best to do a bit of extra work with helpers:

interface ThingCallable {
  (): ValidNumber
}

interface ThingProps {
  toStringProp(): string
}

type Thing = ThingCallable & ThingProps;

const thingCallable: ThingCallable = () => 7;
const thingMixin = { toStringProp() { return 'hi' } };
const thing: Thing = Object.assign(thingCallable, thingMixin);

Or, as suggested in the duplicate question using Object.assign directly:

interface Thing {
  (): ValidNumber
  toStringProp(): string
}

const thing: Thing = Object.assign(
  // Must be a valid () => ValidNumber
  () => 9,
  // Must be a valid superset of the other properties in Thing
  {
    toStringProp() { return 'hello'; }
  }
);
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293