打字稿基于模板变量强制执行函数返回类型

时间:2021-05-27 11:32:53

标签: typescript function templates casting return

在 Typescript 中,您可以重载函数以根据输入参数具有不同的返回类型:

function test2(b: true): {a: number};
function test2(b: false): {x: number};
function test2(b: boolean): {a: number} | {x: number} {
  if(b) return {a: 1};

  return {x: 1};
}

const a_t2: {a: number} = test2(true);
const x_t2: {x: number} = test2(false);

我正在寻找一种在函数本身内部隐式强制执行返回类型的方法。如果你改写这个函数体,Typescript 不会抛出错误:

function test2(b: true): {a: number};
function test2(b: false): {x: number};
function test2(b: boolean): {a: number} | {x: number} {
  // breaking the contract 
  if(b === false) return {a: 1};

  return {x: 1};
}

我最接近工作解决方案的是这个例子,虽然它抛出了一些错误:


function test<B extends boolean>(b: B): B extends true ? {a: number} : {x: number} {
  if(b) {
    // Type '{ a: number; }' is not assignable to type 'B extends true ? { a: number; } : { x: number; }'.(2322)
    return {a: 1};
  } else {
    // Type '{ x: number; }' is not assignable to type 'B extends true ? { a: number; } : { x: number; }'.(2322)
    return {x: 2};
  }
}

const a_t = test(true);  // {a: number}
const x_t = test(false); // {b: number}

我可以通过将返回值转换为:

  if(b) {
    return {a: 1} as B extends true ? {a: number} : never;
  } else {
    return {x: 2} as B extends true ? never : {x: number};
  }

但它违背了对返回值隐式严格的目的。

有人知道更好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

感谢评论,这里有一个类似的问题和答案stackoverflow.com/a/67712372/3388225

它很好地解释了为什么还不能完成我在原始问题中提出的问题,并且有一个 Typescript Github 问题 here 关于这件事。