gpt4 book ai didi

reactjs - TypeScript 允许函数作为 React prop 与函数签名的 in-param 冲突吗?

转载 作者:搜寻专家 更新时间:2023-10-30 21:06:23 25 4
gpt4 key购买 nike

为什么 TypeScript 类型检查器允许带有不严格匹配定义的函数参数的 prop?

具体来说,我定义了一个函数callbackImpl = (str: string): number,并将其作为定义为callback(parameter: string | undefined): number;,这出人意料地有效。

这对我来说很不直观,而且在我看来非常危险!

但是!调用 callbackImpl(undefined) 不起作用,我认为这是正确的。

一个完整的例子:

import React from "react";

interface Props {
callback(parameter: string | undefined): number;
}

class A extends React.Component<Props> {
componentDidUpdate() {
this.props.callback(undefined);
}
}

class B extends React.Component {

private callbackImpl = (str: string): number => {
// Will crash if str is undefined
return str.length;
};

// THIS IS NOT ALLOWED! And rightly so!
private callLocalWithUndefined() {
// TS2345: Argument of type 'undefined' is not assignable to parameter of type 'string'.
this.callbackImpl(undefined);
}

render() {
return (
<React.Fragment>
<A
// This is obviously just as illegal as what happens in callLocalWithUndefined,
// since callbackImpl explicitly does not accept undefined as the first parameter,
// but no type errors here!?
callback={this.callbackImpl}
/>
</React.Fragment>
);
}
}

我在 tsconfig.json 中设置了 "strict": true,

这是一个更完整的 tsconfig.json list ,省略了一些本地内容。

{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": true,
"moduleResolution": "node",
"module": "esnext",
"allowSyntheticDefaultImports": true,
"target": "es6",
"jsx": "react",
"allowJs": true,
"strict": true,
"noEmitOnError": true,
"plugins": [],
"baseUrl": "./",
"paths": {
// Omitted
},
"lib": [
"es2017", // Object.entries support
"dom"
],
"types": ["gapi", "gapi.auth2", "node"]
},
"exclude": [
"node_modules"
]
}

我做错了什么吗?我的 tsconfig 设置有误吗?我是不是误会了什么?

谢谢!

编辑

Titian Cernicova-Dragomir 回答后的其他资源

最佳答案

你是对的,这是不安全的。允许此行为以简化从 JS 到 TS 的迁移是有原因的。好消息是,您可以使用 strictFunctionTypes 选择不允许这样做。

例如这段代码

declare const callbackImpl: (str: string) => number

let callback: (parameter: string | undefined) => number;

callback = callbackImpl

callback(undefined);

上面的代码使用 strictNullChecks 编译,尽管它并不像您注意到的那样完全类型安全。但它将无法同时使用 strictNullChecksstrictFunctionTypes

进行编译

注意 我假设你已经在使用 strictNullChecks 如果你没有那么代码会按预期工作因为没有这个选项 string|undefined 是根据定义只是 string

编辑

上面的一般解释是在问题包含实际代码之前发布的。编译器没有捕获错误的原因是因为您将回调定义为方法。如果将其定义为函数字段,编译器会捕获错误。 我仍然不确定为什么 见下文:

interface Props {
callback: (parameter: string | undefined) => number;
}

class A extends React.Component<Props> {
componentDidUpdate() {
this.props.callback(undefined);
}
}

class B extends React.Component {

private callbackImpl = (str: string): number => {
// Will crash if str is undefined
return str.length;
};


render() {
return (
<React.Fragment>
<A
// Error now
callback={this.callbackImpl}
/>
</React.Fragment>
);
}
}

编辑

此行为是设计使然。 -strictFunctionTypes 标志不适用于原始 PR 中所述的方法

The stricter checking applies to all function types, except those originating in method or construcor declarations. Methods are excluded specifically to ensure generic classes and interfaces (such as Array) continue to mostly relate covariantly. The impact of strictly checking methods would be a much bigger breaking change as a large number of generic types would become invariant (even so, we may continue to explore this stricter mode).

关于reactjs - TypeScript 允许函数作为 React prop 与函数签名的 in-param 冲突吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52641612/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com