简体   繁体   English

TS function 的类型为 ( A | B ),具有单一返回类型 B。如何在不出现类型错误的情况下完成此操作?

[英]TS function having types as ( A | B ), has single return type B. How do i accomplish this without getting type error?

For example here is the simple function:例如这里是简单的 function:

interface InputTime {
      month : number,
      year : number
}

const getMonthAndYear = (time: InputTime | Date): InputTime => {

    if(isValid(time)) {
        // time is a date object
        return {month: time.getMonth(), year: time.getFullYear()}
    } else {
        // time is a month object
        return {...time}
    }
}

So here TypeScript gives 2 errors:所以这里 TypeScript 给出了2个错误:

  1. on first return statement it says: Property 'getMonth' does not exist on type 'InputTime |在第一个返回语句中它说:“输入时间”类型上不存在属性“getMonth”| Date'.日期'。

  2. on Second return statement if fails due to thinking its type Date如果由于认为其类型 Date 而失败,则在第二个返回语句上

So how can i type define this function to work as expected?那么我如何输入定义这个 function 以按预期工作?

Edit:编辑:

Answering the comment about isValid function types:回答关于 isValid function 类型的评论: 在此处输入图像描述

Edit 2:编辑2:

from further reading answers i created this function:通过进一步阅读答案,我创建了这个 function:

const _type_safe_isValidDate = (time:any):time is Date => {
    return isValid(time)
}

And error went away.错误消失了。 But is this the only solution?但这是唯一的解决方案吗? Is there better way so i can write some type guard around those third party library functions that i am using in my code and not create wrapper function just for type safety?有没有更好的方法,所以我可以围绕我在代码中使用的那些第三方库函数编写一些类型保护,而不是为了类型安全而创建包装器 function?

TypeScript does not know from function isValid(date: any): boolean that date is definitely a Date object. TypeScript 不知道从function isValid(date: any): booleandate肯定是Date ZA68CFDE63131C4BEB66 It only knows that isValid returned a boolean .它只知道isValid返回了boolean If you want TypeScript to treat the isValid function as a type assertion it needs to have the following syntax.如果您希望 TypeScript 将isValid function 视为类型断言,则需要具有以下语法。

function isValid(date: any): date is Date {
   // date instanceof Date, etc
}

The relevant section of the TypeScript docs on Type Guards and Differentiating Types . TypeScript 文档中有关类型保护和区分类型的相关部分。

You can easily fix this by updating your custom type guard isValid like:您可以通过更新自定义类型保护isValid来轻松解决此问题,例如:

function isValid(date: any): date is Date {
    return 'getMonth' in date;
}

and then you can call getMonthAndYear() like:然后你可以调用getMonthAndYear()像:

console.log( getMonthAndYear(new Date()) )  
//=> {month: 4, year: 2020}

console.log( getMonthAndYear({month: 1, year: 2020}) )
//=> {month: 1, year: 2020}

In case you have a very complex interface with lots of properties, then you can add an additional optional prop type?如果你有一个非常复杂的接口,有很多属性,那么你可以添加一个额外的可选道具type? to each interface like:到每个接口,如:

interface InputTime {
  type?: "input-time"
  month: number,
  year: number,
  foo: string,
  bar: boolean,
}

interface InputDate {
  type?: "input-date"
  month2: number,
  year2: number,
  foo2: string,
  bar2: boolean,
}

and then update getMonthAndYear() method like:然后更新getMonthAndYear()方法,如:

const getMonthAndYear = (time: InputTime | InputDate): InputTime => {

    if(time.type === 'input-time') {
        // time is a InputTime object
        return {...time}
    } else if(time.type === 'input-date'){
        // time is a InputDate object
        return {month: time.month2, year: time.year2, foo: time.foo2}
    }
}

So, time.type helps you to determine what kind of interface it is and based on that you can modify the return object to match type InputTime .因此, time.type可以帮助您确定它是哪种接口,并在此基础上您可以修改返回 object 以匹配类型InputTime

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当 Type B 以某种方式“扩展”Type A 时,如何停止 TypeScript 错误“Type A 没有与 Type B 相同的属性” - How to stop TypeScript error 'Type A has no properties in common with Type B' when Type B "extends" Type A in some way $不是b。$ scope.SaveUser中的函数 - $ is not a function at b.$scope.SaveUser FlowType:类型的继承(类型A是类型B的子集...) - FlowType: Inheritance of Types (Type A is a subset of type B …) React TS 中的进度条创建 - 尽管在接口中声明了类型,但隐含的错误类型为“任何” - Progress Bar creation in React TS - getting error implicitly has type 'any' although types are declared in interface TS:如何输入带有默认值的参数的箭头函数? - TS: How do I type an arrow function with a parameter that has a default value? 错误TS2345:类型为'(a:Test,b:Test)=>布尔| 1'不能分配给类型'(a:Test,b:Test)=> number'的参数 - error TS2345: Argument of type '(a: Test, b: Test) => boolean | 1' is not assignable to parameter of type '(a: Test, b: Test) => number' 出现错误:类型“typeof B”不可分配给扩展 A 的 class B 的类型“typeof A” - Getting error: Type 'typeof B' is not assignable to type 'typeof A' for class B that extends A TS7053:元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“{ A:数字; B:数字 - TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ A: number; B: number TS:如何在一个类型上处理多种可能的类型? - TS: How to handle multiple possible types on a single type? 如何在 function 组件中的类型上定义属性? TS2339 错误 - How do i define a property on a Type in a function component? TS2339 ERROR
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM