我不确定为什么Typescript为以下代码给出类型错误:
ElseBB
打字稿抱怨这行BasicBlocks
它表示type ShareData = {
title?: string;
text?: string;
url?: string;
};
// extending window.navigator, which has a type of Navigator
interface Navigator {
share?: (data?: ShareData) => Promise<void>;
}
const isShareable =
window.navigator && window.navigator.share;
const handleShare = async () => {
if (isShareable) {
try {
await window.navigator.share({
text: 'Checkout Verishop!',
title: 'Share Verishop',
url: 'referralUrl',
});
} catch (e) {
window.alert(e);
}
}
};
可能未定义。但是,我使用await window.navigator.share({
来确保share
未被定义。
我也尝试定义isShareable
,如下所示:window.navigator.share
,但会遇到相同的错误。
理想情况下,我可以创建一个函数来检查是否定义了isShareable
并进行类型检查。
可以将以上所有代码粘贴到https://www.typescriptlang.org/play
中谢谢!
答案 0 :(得分:1)
TypeScript当前不允许您将类型保护结果保存在变量中,以供以后尝试使用isShareable
的方式使用。在TypeScript的GitHub问题中,有两个公开的建议要求这样做:microsoft/TypeScript#12184和microsoft/TypeScript#24865。这些问题似乎都没有太大的吸引力,但是我想您可以去解决这些问题,并给他们一个?或描述您的用例(如果有必要的话)。问题很可能是实现并保持编译器性能并不是一件容易的事。
您现在可以做什么?显而易见且令人不满意的答案不是尝试提前进行类型保护,而是在要使用受保护的window.navigator.share
函数之前立即进行保护:
// just do the check inline
const handleShareExplicit = async () => {
if (window.navigator && window.navigator.share) {
try {
await window.navigator.share({ // no error
text: "Checkout Verishop!",
title: "Share Verishop",
url: "referralUrl"
});
} catch (e) {
window.alert(e);
}
}
};
这还不是很糟糕,因为它还很简洁... (window.navigator && window.navigator.share)
仍然可以放在一行上。但是有些人可能会遇到类似的问题,其中类型防护是一个更为复杂的检查,或者您可能在哲学上反对多次进行检查。在这种情况下,您可以尝试其他方法:
// store a reference to the function if it exists
const share =
window.navigator && window.navigator.share
? window.navigator.share // .bind(window.navigator) ?? see note below
: undefined;
const handleShare = async () => {
if (share) {
try {
await share({ // no error
text: "Checkout Verishop!",
title: "Share Verishop",
url: "referralUrl"
});
} catch (e) {
window.alert(e);
}
}
};
存储类型为boolean
的等效变量isShareable
而不是存储类似share
的变量((data?: ShareData) => Promise<void>) | undefined
。然后,检查if (share) { share(...) }
具有与您所做的相同的语义,只是在这种情况下,编译器可以轻松地看到您正在使用刚刚检查的内容。
(请注意,根据实现window.navigator.share()
的方式,可能需要将this
上下文设为window.navigator
。如果是这样,则可能需要将share
保存为window.navigator.share.bind(window.navigator)
而不只是window.navigator.share
。在任何情况下,这样做都无妨。这取决于您。)
好的,希望能有所帮助。祝你好运!
答案 1 :(得分:0)
您可以使用类型转换来确保导航器具有share方法,并且您需要使share
成为必需的道具,因为您拥有它的方式可能是不确定的。围栏中的此代码没有错误。
type ShareData = {
title?: string;
text?: string;
url?: string;
};
// extending window.navigator, which has a type of Navigator
interface Navigator {
share: (data?: ShareData) => Promise<void>;
}
const nav = window.navigator as Navigator;
const handleShare = async () => {
try {
await nav.share({
text: 'Checkout Verishop!',
title: 'Share Verishop',
url: 'referralUrl',
});
} catch (e) {
window.alert(e);
}
}
};
答案 2 :(得分:0)
您可以使用type guard帮助TypeScript安全地确定变量的接口。例如,
type ShareData = {
title?: string;
text?: string;
url?: string;
};
// extending window.navigator, which has a type of Navigator
interface SharableNavigator extends Navigator {
share: (data?: ShareData) => Promise<void>;
}
function isSharableNavigator(nav: Navigator): nav is SharableNavigator {
return typeof (nav as SharableNavigator).share === 'function';
}
const handleShare = async () => {
if (isSharableNavigator(window.navigator)) {
try {
await window.navigator.share({
text: 'Checkout Verishop!',
title: 'Share Verishop',
url: 'referralUrl',
});
} catch (e) {
window.alert(e);
}
}
};