首页 > 解决方案 > 如何通过 TypeScript 中的参数对象形状重载函数?

问题描述

假设我想以2 种方式(固定或范围)检查字符串的长度:

/* 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

我首先声明了 2 个接口,如下所示:

interface StringFixed {
  length: number;
}

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

然后我尝试编写函数:

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
  }
}

但是现在 TypeScript 在函数的第一行报告了错误:

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

我的问题是如何在 TypeScript 中做到这一点?

标签: typescriptfunctionoverloading

解决方案


你是如此接近。:-) 您正在询问您希望存在的属性值的类型(typeof schema.length)。要实现类型保护,您需要询问属性是否存在:

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

TypeScript 操场上的工作副本


推荐阅读