我正在创建一个处理数据库中对象的函数。我有两个不同的数据结构,其中相同的属性具有不同的名称。我不能改变它,所以我必须用JavaScript来处理它 对象有其他差异,但这对此功能并不重要 我想对两种不同类型的对象使用相同的函数。以下示例代码演示了我的问题:
interface TypeA {
itemName: string;
}
interface TypeB {
itemTitle: string;
}
function getItemName(item: TypeA | TypeB): string {
let name = '';
if (item.hasOwnProperty('itemName')) {
name = item.itemName;
} else {
name = item.itemTitle;
}
return name;
}
当然,此代码运行。但IDE会将行name = item.itemName;
和name = item.itemTitle;
标记为错误(“属性不存在于类型中”),因为这两种类型都不具有这两种属性。
那么,正确的打字方式是什么?
答案 0 :(得分:4)
您需要创建一个User Defined Type Guard,然后您可以使用if语句并获得正确的输入。
function isTypeA(value: TypeA | TypeB): value is TypeA {
return value.hasOwnProperty('itemName');
}
然后你可以让打字更清洁:
function getItemName(item: TypeA | TypeB): string {
return isTypeA(item) ? item.itemName : item.itemTitle;
}
查看here。项目正确地转换为TypeA或TypeB。
答案 1 :(得分:1)
Intellij接受这种语法:
function getItemName(item: TypeA): string;
function getItemName(item: TypeB): string;
function getItemName(item): string {
return item.hasOwnProperty('itemName') ? item.itemName : item.itemTitle;
}
根据打字稿文件的官方方式是这样的: https://www.typescriptlang.org/docs/handbook/functions.html
答案 2 :(得分:1)
如果你不经常这样做,你可以做出类型断言:
if (item.hasOwnProperty('itemName')) {
name = (item as TypeA).itemName;
} else {
name = (item as TypeB).itemTitle;
}
或
if (item.hasOwnProperty('itemName')) {
name = (<TypeA>item).itemName;
} else {
name = (<TypeB>item).itemTitle;
}
如果你需要进行一次或两次以上的检查,你最好像@Daryl建议的那样写一个打字卫士。
答案 3 :(得分:1)
我可能会迟到,但你可以在你的函数中试试这个:
if ('itemName' in item) {
name = item.itemName;
} else {
name = item.itemTitle;
}
答案 4 :(得分:0)
使用typeguards:
interface TypeA {
itemName: string;
}
interface TypeB {
itemTitle: string;
}
function isTypeA(val: any): val is TypeA
{
return val.hasOwnProperty('itemName');
}
function isTypeB(val: any): val is TypeB
{
return val.hasOwnProperty('itemTitle');
}
function getItemName(item: TypeA | TypeB): string
{
let name = '';
if (isTypeA(item))
{
name = item.itemName;
}
else
{
name = item.itemTitle;
}
return name;
}
答案 5 :(得分:0)
我不会让事情变得复杂。如果您确定您的对象具有该属性,则name = item['itemName'] || item['itemTitle']
或name = item.hasOwnProperty('itemName') ? item['itemName'] : item['itemTitle']
就足够了。
请注意,如果使用括号表示法而不是点表示法访问属性,则TypeScript通常会停止抱怨。不过,我建议添加评论。