简体   繁体   中英

How to overload function by argument object shape in TypeScript?

Suppose I want to check the string's length, in 2 ways (fixed or range):

/* Fixed check */
check('abc', {length: 1}); // false
check('abc', {length: 3}); // true

/* Range check */
check('xyz', {minLength: 5, maxLength: 10}); // false
check('xyz', {minLength: 1, maxLength: 10}); // true
check('xyz', {minLength: 3, maxLength: 3}); // true

I first declared the 2 interfaces as follows:

interface StringFixed {
  length: number;
}

interface StringRange {
  minLength: number;
  maxLength: number;
}

Then I try to write the function:

function check(value: string, schema: StringFixed): boolean;
function check(value: string, schema: StringRange): boolean;
function check(value: string, schema: StringFixed | StringRange): boolean {
  if (typeof schema.length !== 'undefined') { // ERROR
    // Fixed check
  } else {
    // Range check
  }
}

But now the TypeScript reports the ERROR in the first line of the function:

TS2339: Property 'length' does not exist on type 'StringFix | StringRange'

My question is how to do this in TypeScript?

You're so close. :-) You're asking for the type of the value of a property that you expect to be there ( typeof schema.length ). To implement a type guard , you want to ask if the property is there:

if ("length" in schema) {
    // Fixed check
} else {
    // Range check
}

Working copy on the TypeScript playground .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM