请教一个ts类型定义的写法

例如我定义了两个接口的入参类型:

interface ParamsA {
  a: string;
}

interface ParamsB extends ParamsA {
  b: number;
}

然后有两个接口apiAapiB

const param: ParamsA | ParamsB = {
  a: 'xxx'
}

if (/* 某个成立的条件 */) {
  param.b = 0 // 但是在这里就提示说 ParamsA 没有 b 属性
  apiA(param)
} else {
  apiB(param)
}

目前处理方式是这样的(但我想用上面那种方法,还是说我上面那种定义param的时候就错了?):

const param: ParamsA = {
  a: 'xxx'
}

if (/* 某个成立的条件 */) {
  (param as ParamsB).b = 0 // 这里就没问题了
  apiA(param as ParamsB)
} else {
  apiB(param)
}

之前还有写一种方法就是把b写成可选的,但是我是想明确区分apiAapiB的入参类型,所以就没有这么写

interface ParamsA {
  a: string;
  b?: number;
}

不知道大佬能不能理解我的意思?我记得我之前好像看过在if()里面可以直接把param的类型判断好,但是我if又没有用到param,所以不太知道这里怎么写,请大佬指点一下~


更新一下,看到@搬砖工 大佬的回答确实我一开始是没看懂的,所以就没有在意,后面发现好像有点不对劲,才认真去思考了一下这个回答,确实需要自我批评一下,理论上这个就是我需要的答案,关键就在于in这个关键字在ts中的作用以及ts的版本问题导致我在考虑这个回答的时候没有采纳,因为我去试了一下ts推导出来的是never,不是我想要的ParamsB(只有在一开始定义了b的话才能正确推导出ParamsB,但其实这样子也没有意义了)。但为什么在ts 3.7.5能正确推导而在后面就不能了我好像还是没有翻到答案,不过我觉得应该这里用in是没问题的。
参考:
what-does-the-in-keyword-do-in-typescript
why-is-this-objects-type-resolving-to-one-side-of-a-type-union

阅读 3.1k
5 个回答
if('a' in paramsA){
   params.a........
}
if('b' in paramsA){
   params.b......
}

一、用扩展运算符

if (bol) {
  apiA({...param, b: 0})
} else {
  apiB(param)
}

二、弃用联合类型
ParamsB 是集成自ParamsA的,apiB接受ParamsA也兼容ParamsB

const param: ParamsB = {
  a: '',
  b: 0
}

类型是静态的,条件是动态的,除非在判断中加入可以推导出类型的代码,比如inhasOwnProperty

蹲一下 看看有无其它解

let param: ParamsA | ParamsB = {
  a: 'xxx'
}

你想表达的是:param要么是ParamsA类型,要么是ParamsB类型。薛定谔的猫要么死要么活。但是字面量赋值后param就具有确定的类型了,也就是薛定谔的猫死掉了。之后在整个类型系统中(TypeScript是静态类型检查)param就是ParamsA类型的,不在具有要么要么的特性了。

好在ParamsB extends ParamsA,param不管确定了二者哪一个状态,对于apiA来说都是兼容的。但如果param确定了ParamsA类型,通过as“扩展”到ParamsB类型。

let param: ParamsA | ParamsB = { a: 'xxx' }

if (Math.random() > 0.5) {
    ;(param as ParamsB).b = 12
    apiB(param as ParamsB)
} else {
    apiA(param)
}
interface ParamsA {
  a: string;
}

interface ParamsB extends ParamsA {
  b: number;
}

param:ParamsA

if (/* 某个成立的条件 */) {
  const _param:ParamsB = {
     ...param,
     b:0
  } 

  apiA(_param)
} else {
  apiB(param)
}

这样最清楚,一个种数据一个变量

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题