“导航器”类型上不存在属性“共享”

Posted

技术标签:

【中文标题】“导航器”类型上不存在属性“共享”【英文标题】:Property 'share' does not exist on type 'Navigator' 【发布时间】:2018-05-29 15:04:47 【问题描述】:

我需要在我的 Ionic 应用程序中使用 WebShareAPI。

这是我在Introducing the Web Share API中建议的代码

if (window.navigator && window.navigator.share) 
  window.navigator.share(
    title: 'title',
    text: 'description',
    url: 'https://soch.in//',
  )
    .then(() => console.log('Successful share'))
    .catch((error) => console.log('Error sharing', error));
 else 
  alert('share not supported');

但是,Typescript 编译失败并出现以下错误:

[11:31:11]  typescript: src/pages/channel_home/channel_home.ts, line: 89
            Property 'share' does not exist on type 'Navigator'.

这里解释了一个可能的原因 DOM lib: add support for navigator.share

但是,我想知道一些解决方法,以使 WebShareApi 特别适用于我的 Ionic 应用程序,以及一般的任何 Angular 或 Typescript 应用程序。

【问题讨论】:

这已被添加到全局 dom 类型中:github.com/microsoft/TSJS-lib-generator/pull/837 但是,对我来说,在 Angular 9.1 中我仍然收到错误,这很奇怪。 【参考方案1】:

基于这个answer, 您可以尝试定义any 类型的变量并将您的Type Navigator 值分配给它。该问题与 typeScript 类型有关。

let newVariable: any;

newVariable = window.navigator;

if (newVariable && newVariable.share) 
  newVariable.share(
    title: 'title',
    text: 'description',
    url: 'https://soch.in//',
  )
    .then(() => console.log('Successful share'))
    .catch((error) => console.log('Error sharing', error));
 else 
  alert('share not supported');

另一种选择是扩展界面导航器,正如我在上面发布的链接中所建议的那样。

【讨论】:

你不能简单地使用globals 吗? @FlavienVolken,你的意思是在 globals.d.ts 文件中添加一个新的接口类型?如果变量navigator.share要在项目的不同级别使用,那将是一个不错的选择,否则我将选择按照我在答案中解释的方式进行。 最好将覆盖属性放在他们自己的全局文件(或 typings.ts)中,因为它们只是用于让 typescript 编译器工作,而不是用于真正的开发,并且当类型最终包含属性,您可以轻松找到并删除它【参考方案2】:

这对我有用

let newVariable = (window.navigator as any)
if(newVariable.share)
  newVariable.share(
  title: 'title',
  text: 'description',
  url: 'https://soch.in//',
)
  .then(() => console.log('Successful share'))
  .catch((error) => console.log('Error sharing', error));
 else 
  alert('share not supported');
   

【讨论】:

【参考方案3】:

这也有效,我们不需要创建 newVariable。

if (window.navigator && window.navigator.share) 
  window.navigator['share'](
    title: 'title',
    text: 'description',
    url: 'https://soch.in//',
  )
    .then(() => console.log('Successful share'))
    .catch((error) => console.log('Error sharing', error));
 else 
  alert('share not supported');

【讨论】:

【参考方案4】:

对于任何寻找正确答案的人,只需将其添加到您的 global.d.ts 文件中:

type ShareData = 
    title? : string;
    text? : string;
    url? : string;
;

interface Navigator

    share? : (data? : ShareData) => Promise<void>;

这恰当地反映了 1 级 API。

【讨论】:

【参考方案5】:

就我而言:在 Angular 中,在我使用的模块上:

navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;

并且打字稿显示错误 MozGetUserMedia 不是属性。

我修复了:

declare const navigator: any; 

也许同样的方法也适合你:

【讨论】:

【参考方案6】:

[2020 年更新]

这在 Typescript 的最新版本中已修复(我不确定是哪一个,但我猜是 v4.3-beta 版本)。检查此线程以获取详细信息 - https://github.com/microsoft/TypeScript/issues/18642

另外, 下面分享的示例,一旦更新到最新版本将不起作用,因为它与 Typescript 自己的类型冲突。因此,不要应用这些更改或保持与父类型相似的类型:

// global.d.ts
interface Navigator extends Navigator 
  share: (options?: ShareData) => Promise<void>;

share 属性已从可选中删除,根据规范,详细信息implemented in Firefox、changes in Firefox


我们可以通过Typescript 方式做到这一点:

首先,我们需要为我们的项目定义自定义类型。所以,我们需要在你的根目录下定义一个/typings/@types 文件夹。

.
└── typings

完成后,您需要更新您的 tsconfig.json 文件以将新的自定义类型文件夹指向此文件夹。


  "compilerOptions": 
    ...
    "typeRoots": [
      "./node_modules/@types",
      "./typings"
    ]
  ,
  "include": [
    ...
    "typings",
    "**/*.ts",
    "**/*.tsx"
  ]
  ...

这将允许 Typescript 在 /typings 文件夹中查找自定义类型。

以上参考:

Angular University Typescript Typings Typescript Docs

完成上述操作后,我们需要创建一个全局.d.ts 文件,Typescript 将查看该文件以检测自定义类型。因此,在您的 /typings 文件夹中创建一个名为 global.d.ts 的新文件。

// global.d.ts
interface Navigator extends Navigator 
  share?: (options: any) => Promise<void>;

我们正在做的是用一些额外的属性来支持默认的Navigator

一旦你声明了上面的接口,Typescript 将允许你使用navigator.share,但是你需要把它放在一个条件块中,因为share 是可选属性,它可能存在也可能不存在于浏览器中。

Typescript Docs on Global Definitions

希望这会有所帮助!

【讨论】:

【参考方案7】:

如果您仍然收到错误消息,尽管遵循了本网站上的建议,请确保您的页面是通过 https 的服务器。共享功能在普通 http 上不可用。以下剪辑对我有用。

const nav: any = window.navigator;
nav.share( title: "Shared via my https page", url: "relativeLink" )

【讨论】:

【参考方案8】:

navigator 声明为any

(window.navigator as any).share

【讨论】:

以上是关于“导航器”类型上不存在属性“共享”的主要内容,如果未能解决你的问题,请参考以下文章

错误 TS2339:“导航器”类型上不存在属性“相机”

类型“typeof ...”上不存在属性“use”,类型“typeof”上不存在属性“extend”

TypeScript:类型“”上不存在属性

错误 TS2339:类型“”上不存在属性“包含”

类型“”上不存在属性“forEach”

类型“”上不存在 Typescript 错误属性“成员”