[英]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个错误:
on first return statement it says: Property 'getMonth' does not exist on type 'InputTime |在第一个返回语句中它说:“输入时间”类型上不存在属性“getMonth”| Date'.
日期'。
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): boolean
那date
肯定是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.