TypeScript在使用之前没有检测到这些检查。

huangapple go评论57阅读模式
英文:

TypeScript is not detecting the checks before usage

问题

所以我一直在尝试弄清楚如何让TS在使用变量之前检查它们是否存在。以下是代码:

这是检查的函数:

function envChecks(){
  if (!process.env.DRIVER_PATH) {
    throw new Error('Environment variable DRIVER_PATH is not set');
  }
}

这是如何使用它的:

export async function thisDoesSomething() {

  envChecks();

  const pathToDriver = path.resolve(process.env.DRIVER_PATH); // <- 这一行给我一个TS错误
  // ...更多代码
}

这是TS错误:

Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
  Type 'undefined' is not assignable to type 'string'.ts(2345)

如果我在使用之前进行检查(而不是在函数中),它就不会抱怨。但我更喜欢更清晰的代码。

英文:

So I've been trying to figure out how can I get TS to see I'm checking my variables exist before I use them? Here's the code :

This is the function that checks

function envChecks(){
  if (!process.env.DRIVER_PATH) {
    throw new Error(&#39;Environment variable DRIVER_PATH is not set&#39;);
  }
}

This is how it's used :


export async function thisDoesSomething() {

  envChecks();

  const pathToDriver = path.resolve(process.env.DRIVER_PATH); &lt;- This Line here is give me a TS error
  // ...more code here
}

This is the TS error :

Argument of type &#39;string | undefined&#39; is not assignable to parameter of type &#39;string&#39;.
  Type &#39;undefined&#39; is not assignable to type &#39;string&#39;.ts(2345)

If I check before the usage (not in a function), it doesn't complain then. But I prefer cleaner code.

答案1

得分: 1

一个非常简单的方法是让你的检查函数返回正确类型的数据或抛出异常。首先定义一个描述所需数据的接口:

interface TheData {
  driverPath: string;
  foo: number;
  bar: boolean;
  ...
}

现在将任何输入传递给检查函数,并将接口作为返回值:

function envChecks(env: ProcessEnv, baz: SomeOtherType): TheData {
  if (!env.DRIVER_PATH) {
    throw new Error('环境变量 DRIVER_PATH 未设置');
  }
  // 现在 driverPath 的类型是 string,而不是 string | undefined
  const driverPath = env.DRIVER_PATH;

  if (typeof baz.foo !== 'number') {
    throw new Error('baz.foo 不是一个数字');
  }
  const foo = +baz.foo;

  // 其他检查...

  return {
    driverPath,
    foo,
    bar
  };
}

使用它也很简单:

export async function thisDoesSomething() {

  const theData = envChecks();

  const pathToDriver = path.resolve(theData.driverPath);
  // ...更多代码
}

可能还有更复杂的方法,比如使用类型守卫,但我相信这对你的情况已经足够了。

英文:

A very simple way is to have your check function actually return the properly typed data or throw. Start by defining an interface that describes the data you will be needing:

interface TheData {
  driverPath: string;
  foo: number;
  bar: boolean;
  ...
}

Now feed any input to the check function and have it return the interface as:

function envChecks(env: ProcessEnv, baz: SomeOtherType): TheData {
  if (!env.DRIVER_PATH) {
    throw new Error(&#39;Environment variable DRIVER_PATH is not set&#39;);
  }
  // Now this is properly typed to string, NOT string | undefined
  const driverPath = env.DRIVER_PATH;

  if (typeof baz.foo !== &#39;number&#39;) {
    throw new Error(&#39;baz.foo is not a number&#39;);
  }
  const foo = +baz.foo;

  // and so on...

  return {
    driverPath,
    foo,
    bar
  };
}

Using it is straightforward:

export async function thisDoesSomething() {

  const theData = envChecks();

  const pathToDriver = path.resolve(theData.driverPath);
  // ...more code here
}

There may be more complicated ways with type guards, but I believe this should do for your case.

huangapple
  • 本文由 发表于 2023年7月27日 15:57:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76777613.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定