首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TypeScript(err:2532):object可能是未定义的清空/未定义检查

TypeScript(err:2532):object可能是未定义的清空/未定义检查
EN

Stack Overflow用户
提问于 2020-07-09 16:39:04
回答 1查看 67关注 0票数 0

我一直在用TypeScript编写一个不和谐的机器人,我添加了一个命令从机场检索信息。您唯一需要提供的是机场的民航组织代码(识别机场的4个字符代码)。现在:很明显,用户可能会搞错国际民航组织的代码,可能会给出无效的代码。这就是为什么我有一个从JSON检索机场对象的方法,它看起来有点像这样(不是一个精确的副本,只是为了让您了解它):

代码语言:javascript
复制
public getAirport(icao: string): Airport | undefined {
    return arrayOfAllAirports.find(ap => ap.icao === icao);
}

在我的命令文件/类中,我使用此方法明显地使用给定的民航组织代码检索机场。然后我检查它的返回值是否是未定义的,如果是的话,我是return *some error*,就是这样。看起来就像这样:

代码语言:javascript
复制
let airportMgr = new AirportManager();
    
let airport = airportMgr.getAirport(icao);
if (airport === undefined) {
    return *invalid icao error*;
}

*blablabla*

let exampleString = `ICAO: ${airport.icao} | Name: ${airport.name}`;
                                    ^error here             ^error here

但是在我使用上述方法的两个文件/类以及上述检查中,我会得到一个更低的错误,对象可能是未定义的。现在出现了更令人困惑的地方:低几行。我又进入了“机场”的一些财产,却什么也没说。

现在我知道当我检索机场或重新分配它时我可以使用as Airport,但是我想要一个正确的解决方案,而不是以愚蠢的方式欺骗类型记录。你们中有谁对如何处理这个问题有什么想法吗?

编辑:

这是它的工作地点的图片:https://i.stack.imgur.com/tTZyJ.png

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-09 16:48:00

问题是您使用的是let,而不是constlet可以重新分配,这意味着每次可能发生更改时,它的类型都会被扩展到原来的类型。就像这样:

代码语言:javascript
复制
// I made it async to demonstrate something below, for your case it is not important
async function doStuff() {
  // Some icao code
  const icao = 'some icao';
  let airport: Airport | undefined = getAirport(icao);

  // Let's start by checking whether the airport is undefined
  if (airport === undefined) {
    return;
  }

  // And now let's break down all the scenarios that work
  // and then all the ones that don't
  //
  // The important concept here is called lexical scope,
  // an "environment" in which variables and constants are defined

  // 1. current lexical scope - the scope of this function
  //
  // This should work since the value of airport has just been checked
  // and has not had an opportunity to be changed
  airport.name;

  // 2. "child" lexical scope - scope created by a function defined within
  // the current lexical scope
  // 
  // This should not work since you might be calling this function
  // some later time, when the value of airport would have possibly changed
  function someHelperFunction() {
    airport.name;
  }

  // The same applies to promise resolution values
  Promise.resolve().then(() => {
    // This should not work
    airport.name
  });

  // It works with simple awaits
  const anything = await Promise.resolve('something');
  // This will work
  airport.name;

  // A TRICK (!!!)
  //
  // You can at this point create a const of type Airport (because now you are sure
  // it is an airport) and use that in your functions.
  //
  // Since it is defined as const, it cannot be changed 
  // and it will stay an airport like forever and ever
  const airportForSure: Airport = airport;
  function someOtherHelperFunction() {
    // WORKS!!!
    airportForSure.name;
  }

  Promise.resolve().then(() => {
    // Yesss
    airportForSure.name
  });

  // Then when you change the value of airport, you need to check for undefined again
  airport = getAirport(icao);

  // This will not work
  airport.name;
}

type Airport {
  icao: string;
  name: string;
}

// Just a placeholder for a function
declare function getAirport(icao: string): Airport | undefined;

链接到TypeScript操场

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62819629

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档