【问题标题】:'Property does not exist on type 'never''从不'类型上不存在属性
【发布时间】:2017-10-24 04:21:27
【问题描述】:

这类似于#40796374,但这是围绕类型,而我正在使用接口。

给定下面的代码:

interface Foo {
  name: string;
}

function go() {
  let instance: Foo | null = null;
  let mutator = () => {
   instance = {
     name: 'string'
   };  
  };

  mutator();

  if (instance == null) {
   console.log('Instance is null or undefined');
  } else {
   console.log(instance.name);
  }
}

我有一个错误提示“从不”类型上不存在“属性”名称。

我不明白实例怎么可能是“从不”。任何人都可以对此有所了解吗?

【问题讨论】:

  • 从您的代码中可以清楚地看出,else 确实永远不会得到评估。编译器足够聪明,可以看到它。
  • 这是一个例子,让我再添加一些代码表明它仍然存在问题。
  • It's pretty clear from your code that the else would indeed never get evaluated. 这一点都不明显,也没有智能编译器。有一个愚蠢的转译器,它偏离了既定的做法。例如,在 C# 中,可以将null 分配给任何对象...
  • @BozhidarStoyneff,这是成立但遗憾的做法:en.wikipedia.org/wiki/Null_pointer#History
  • 当与 try catch finally 变量一起使用时,这将成为一个严重的头痛问题,这些变量需要在 finally 块中处理..

标签: typescript


【解决方案1】:

如果你将 Component 编写为 React.FC,并使用 useState(),

这样写会有帮助:

const [arr, setArr] = useState<any[]>([])

【讨论】:

  • 这解决了我的问题,我无法将类型分配给arr 作为arr: any
  • 今天连续 17 小时处理一个问题后,这是根本问题和解决方案。谢谢
  • 谢谢。你救了我。我在这个错误上投入了大量的时间和精力。
  • 请问为什么这可以解决问题?这只是添加了额外的不必要的 Typescript,还是实际上让他的代码更安全?
  • @blue-hope 也很想听听解释。
【解决方案2】:

因为您将instance 分配给null。编译器推断它永远不会是null 以外的任何东西。所以它假定 else 块永远不应该被执行,所以 instance 在 else 块中被输入为 never

现在,如果您不将其声明为字面值 null,并通过任何其他方式获取它(例如:let instance: Foo | null = getFoo();),您将看到 instance 在 if 块内将是 nullFoo 在 else 块中。

从不输入文档:https://www.typescriptlang.org/docs/handbook/basic-types.html#never

编辑:

更新示例中的问题实际上是编译器的一个未解决问题。 见:

https://github.com/Microsoft/TypeScript/issues/11498 https://github.com/Microsoft/TypeScript/issues/12176

【讨论】:

【解决方案3】:

我遇到了同样的错误,并用括号表示法替换了点表示法以抑制它。

例如:

obj.name -> obj['name']

【讨论】:

  • 这是一个错误吗?也为我工作。为什么点符号不起作用?
【解决方案4】:

这似乎与此问题相似:False "Property does not exist on type 'never'" when changing value inside callback with strictNullChecks,作为此问题的副本(讨论)已关闭:Trade-offs in Control Flow Analysis

这个讨论很长,如果你在那里找不到好的解决方案,你可以试试这个:

if (instance == null) {
    console.log('Instance is null or undefined');
} else {
    console.log(instance!.name); // ok now
}

【讨论】:

  • 谢谢@Nitzan。这正是我在代码中所做的,
  • 在某些情况下,我仍然得到同样的错误,即使我使用这种方法,比如a!.b!.c,并告诉Property c ...
  • “!”的解释运营商在这个答案中:stackoverflow.com/a/42274019/1393400
【解决方案5】:

如果您收到参数错误,请保留anyany[] 输入类型,如下所示

getOptionLabel={(option: any) => option!.name}
 <Autocomplete
    options={tests}
    getOptionLabel={(option: any) => option!.name}
    ....
  />

【讨论】:

  • 就我而言,用any 注释参数对我有用:this.state.projects.map((project: any, idx) =&gt; &lt;Project key={idx} title={project.name}/&gt;)
  • 因为这也适用于我,但是我们没有利用接口分辨率。
【解决方案6】:

在我自己的情况下,当我启动数组时。我用过:

selectedActors: any = [];

所以它一开始是“动态的”

【讨论】:

    【解决方案7】:

    对我来说,以下代码正在运行:

    const [disc, setDisc] = useState<any[]>([]);
    

    到目前为止,我所看到的情况如下:当您没有指定要传递给 useState() 的类型时,它会推断它是从不类型。 通过使用 any[],您可以在请求时传递数据。

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    【解决方案8】:

    就我而言(我使用的是打字稿),我试图用稍后分配数据的假数据来模拟响应。我的第一次尝试是:

    let response = {status: 200, data: []};
    

    然后,在分配虚假数据时,它开始抱怨不能分配类型“never[]”。 然后我定义了如下响应并接受它..

    let dataArr: MyClass[] = [];
    let response = {status: 200, data: dataArr};
    

    并分配假数据:

    response.data = fakeData;
    

    【讨论】:

      【解决方案9】:

      就我而言,这是因为我没有输入变量。

      所以我创建了搜索界面

      export interface Search {
        term: string;
        ...
      }
      

      我改了

      searchList = [];
      

      为此,它奏效了

      searchList: Search[];
      

      【讨论】:

        【解决方案10】:

        我遇到了问题?还有!

        这件作品对我有用。

        if (ref != null){
            if (ref.current != null)
                ref.current.appendChild(child);
        }
        

        【讨论】:

          猜你喜欢
          • 2021-12-30
          • 2017-04-09
          • 2018-03-09
          • 2021-12-03
          • 2021-05-18
          • 2021-01-09
          • 2021-07-10
          • 2020-03-27
          相关资源
          最近更新 更多