为什么这会给出一个Typescript警告?

为什么这会给出一个Typescript警告?,typescript,create-react-app,react-router-dom,Typescript,Create React App,React Router Dom,为什么在这个.tsx组件中对的第二次调用需要字符串(var1)给出警告,而不是第一次或第三次调用?如果我将代码更改为使用var2而不是var1(我认为它们具有完全相同的类型),则不会收到警告。有什么好处 import { useParams } from "react-router-dom"; const DeleteTeams2 = ({ var2 } : { var2: string | undefined})=> { // use var here so that var1

为什么在这个.tsx组件中对
的第二次调用需要字符串(var1)
给出警告,而不是第一次或第三次调用?如果我将代码更改为使用
var2
而不是
var1
(我认为它们具有完全相同的类型),则不会收到警告。有什么好处

import { useParams } from "react-router-dom";

const DeleteTeams2 = ({ var2 } : { var2: string | undefined})=> {
    // use var here so that var1 and var2 get exactly the same types
    var { var1 } = useParams();

    function needsString(str : string) : string {
        return "hello";
    }

    // I can tell typescript that var1
    // definitely is non-null with an if statement
    if (! var1)
        throw new Error("bad, bad varN");

    // This call is warning-free
    needsString(var1);

    // But JSX doesn't know that var1 is non-null for some reason...
    return (
        <div
            onClick={() => {
                // I get a warning from this!
                needsString(var1);
            }}
        >
            { needsString(var1) }
        </div>
    )
}

编辑:删除了对的引用,因为我没有使用非空断言运算符,正如一些注释所指出的那样。

问题在于这里的代码:

onClick={() => {
  // I get a warning from this!
  needsString(var1);
}}
不会与此代码同时执行:

if (! var1)
  throw new Error("bad, bad varN");

// This call is warning-free
needsString(var1);
此外,
var1
是一个可变引用,因此从TypeScript的角度来看,它可能会在检查它是否为空和实际使用它之间发生变化。例如,考虑这个示例代码:

//它已填充
var myVar=“你好”;
//验证它是否已填充
如果(!myVar)抛出错误(“错误!”);
//绝对肯定地说,“myVar”已填充
//将此设置为稍后执行
setTimeout(()=>console.log(“myVar”,myVar));
//改变它

myVar=未定义问题在于此处的代码:

onClick={() => {
  // I get a warning from this!
  needsString(var1);
}}
不会与此代码同时执行:

if (! var1)
  throw new Error("bad, bad varN");

// This call is warning-free
needsString(var1);
此外,
var1
是一个可变引用,因此从TypeScript的角度来看,它可能会在检查它是否为空和实际使用它之间发生变化。例如,考虑这个示例代码:

//它已填充
var myVar=“你好”;
//验证它是否已填充
如果(!myVar)抛出错误(“错误!”);
//绝对肯定地说,“myVar”已填充
//将此设置为稍后执行
setTimeout(()=>console.log(“myVar”,myVar));
//改变它

myVar=未定义const{var1}
,由于if语句和非空断言运算符,…“您的
”,则code>可能会工作中的code>如果
不是非空断言运算符,则它只是否定运算符。非空断言运算符是后缀运算符,不用于逻辑流。但是,
如果
应该起到保护作用,这只是一个术语注释。:-)@VLAZ-它也应该与
let
一起工作,前提是
var1
在保护和使用之间没有被修改。感谢您的评论,我实际上没有使用非null断言运算符。我对问题进行了编辑,不想这样说。您使用什么编译器和生成器可以包含更多信息?如果您有
const{var1}
,可能会工作,因为if语句和非空断言运算符,…“您的
中的code>如果
不是非空断言运算符,则它只是否定运算符。非空断言运算符是后缀运算符,不用于逻辑流。但是,
如果
应该起到保护作用,这只是一个术语注释。:-)@VLAZ-它也应该与
let
一起工作,前提是
var1
在保护和使用之间没有被修改。感谢您的评论,我实际上没有使用非null断言运算符。我对问题进行了编辑,不想这样说。你使用什么编译器和生成器?你能提供更多信息吗?@T.J.Crowder我删除了一些注释和死代码。正如OP所说,回调中似乎出现了错误。在TS配置中,确保将JSX设置为React(我认为这是默认设置)。然后我通过从“React”中导入React来停止抱怨,这让我很惊讶。:-)我原以为我必须去为它获取一个cdnjs或unpkg链接,但这本身就起作用了。@T.J.Crowder我在最后一个例子中使用了“preserve”。奇怪的是,在你的例子中发生了这种情况,但在我的例子中没有(见对问题的评论)。但你的似乎更接近行动的目的,所以。。。在FCs中使用
const
作为状态变量的另一个原因。我不相信这个解释,但
const
似乎确实解决了这个问题。这是有道理的,我的意思是
|未定义的
。:-)但是,从根本上说,这归结为TypeScript编译器并不总是准确地检测到没有任何东西分配给(也没有任何东西可以分配给)变量。这至少在一定程度上是因为TypeScript团队经常就复杂性和功能与编译速度之间的关系做出务实的决定。@T.J.Crowder我删除了一些注释和死代码。正如OP所说,回调中似乎出现了错误。在TS配置中,确保将JSX设置为React(我认为这是默认设置)。然后我通过从“React”中导入React来停止抱怨,这让我很惊讶。:-)我原以为我必须去为它获取一个cdnjs或unpkg链接,但这本身就起作用了。@T.J.Crowder我在最后一个例子中使用了“preserve”。奇怪的是,在你的例子中发生了这种情况,但在我的例子中没有(见对问题的评论)。但你的似乎更接近行动的目的,所以。。。在FCs中使用
const
作为状态变量的另一个原因。我不相信这个解释,但
const
似乎确实解决了这个问题。这是有道理的,我的意思是
|未定义的
。:-)但是,从根本上说,这归结为TypeScript编译器并不总是准确地检测到没有任何东西分配给(也没有任何东西可以分配给)变量。这至少在一定程度上是因为TypeScript团队经常就复杂性、能力和编译速度做出务实的决定。