带有扩展运算符的 TypeScript React setState
TypeScript React setState with spread operator
我有这个界面。
interface parts {
general: boolean,
source: boolean,
target: boolean
}
当在 Parent 组件中初始化状态并使用该接口键入它时,TypeScript 会按预期工作。
const Parent: React.FC = () => {
const [parts, setParts] = useState<parts>({
general: false,
source: false,
target: false,
wrongKey: "Typescript reports problem"
})
return (
<Child setParts={setParts} />
)
}
但是当它传递给 child 时,TypeScript 无法按预期工作。
const Child: React.FC<{setParts: React.Dispatch<React.SetStateAction<parts>> }> =({setParts}) => {
setParts((parts: parts) => {
...parts,
wrongKey: "Typescript doesn't report problem"
})
return (
<div></div>
)
}
对于布尔值或字符串等类型,它可以正常工作,但字典存在一些问题。
Excess 属性 检查仅在您尝试分配对象文字时触发。对于其他情况,TypeScript 仅检查对象的形状是否与请求的类型匹配。原因是当您内联传递错误形状的对象时,很可能是开发人员错误。允许这样做有什么好处?所以这是一个错字或者你想要别的东西。
但是如果你传递一个变量,它只需要检查形状是否正确,就不会有任何 运行时间问题。例如,您可以执行以下操作:
const [parts, setParts] = useState<parts>({
general: false,
source: false,
target: false,
wrongKey: "Typescript reports problem"
} as parts)
这样 TypeScript 将确保您传递 'something',它可以被整形为 parts
。不知道有没有用,举个例子吧:)
我不确定这是否真的是您不知道传递无关 属性 的问题。我想强调一下,如果您 忘记 传递 属性 来满足所需类型的形状,TypeScript 会告诉您这一点,这很重要。
如果你真的想拒绝额外的属性,请检查这个答案:
更新 1:
为什么没有触发 excess 属性 检查,因为实际上我们 return 使用对象文字,我说 excess 属性 check 运行 在那种情况下,这有点矛盾,但是其实不是。
考虑这个例子:
type Parts = {
general: boolean;
source: boolean;
target: boolean;
}
type FunctionType = (parts: Parts) => Parts;
function ShowsError(parts: Parts): Parts {
return {
...parts,
someExtraPropertyWhichTriggerError:'Ooops'
}
}
const myArrowFunction = (parts: Parts) => ({
...parts,
someExtraPropertyWithoutError:'Why no report?:('
});
const DoesntShowError: FunctionType = myArrowFunction;
那么那里发生了什么?貌似是两个一模一样的函数,一个是箭头函数,一个是普通函数,为什么是箭头函数就没有错误呢?相同的参数,相同的 return 类型,相同的对象 returned.
关键区别在于,当我们定义箭头函数时,其 return 语句 NOT 上下文绑定到部件。 TypeScript 无法知道它要用在什么地方。所以它为其 return 类型生成一个形状,然后继续。
然后我们将它分配给 DoesntShowError
这需要我们分配给定类型的函数。而箭头函数满足了这个要求。我想就这些了,希望对你有帮助。
我有这个界面。
interface parts {
general: boolean,
source: boolean,
target: boolean
}
当在 Parent 组件中初始化状态并使用该接口键入它时,TypeScript 会按预期工作。
const Parent: React.FC = () => {
const [parts, setParts] = useState<parts>({
general: false,
source: false,
target: false,
wrongKey: "Typescript reports problem"
})
return (
<Child setParts={setParts} />
)
}
但是当它传递给 child 时,TypeScript 无法按预期工作。
const Child: React.FC<{setParts: React.Dispatch<React.SetStateAction<parts>> }> =({setParts}) => {
setParts((parts: parts) => {
...parts,
wrongKey: "Typescript doesn't report problem"
})
return (
<div></div>
)
}
对于布尔值或字符串等类型,它可以正常工作,但字典存在一些问题。
Excess 属性 检查仅在您尝试分配对象文字时触发。对于其他情况,TypeScript 仅检查对象的形状是否与请求的类型匹配。原因是当您内联传递错误形状的对象时,很可能是开发人员错误。允许这样做有什么好处?所以这是一个错字或者你想要别的东西。
但是如果你传递一个变量,它只需要检查形状是否正确,就不会有任何 运行时间问题。例如,您可以执行以下操作:
const [parts, setParts] = useState<parts>({
general: false,
source: false,
target: false,
wrongKey: "Typescript reports problem"
} as parts)
这样 TypeScript 将确保您传递 'something',它可以被整形为 parts
。不知道有没有用,举个例子吧:)
我不确定这是否真的是您不知道传递无关 属性 的问题。我想强调一下,如果您 忘记 传递 属性 来满足所需类型的形状,TypeScript 会告诉您这一点,这很重要。
如果你真的想拒绝额外的属性,请检查这个答案:
更新 1: 为什么没有触发 excess 属性 检查,因为实际上我们 return 使用对象文字,我说 excess 属性 check 运行 在那种情况下,这有点矛盾,但是其实不是。
考虑这个例子:
type Parts = {
general: boolean;
source: boolean;
target: boolean;
}
type FunctionType = (parts: Parts) => Parts;
function ShowsError(parts: Parts): Parts {
return {
...parts,
someExtraPropertyWhichTriggerError:'Ooops'
}
}
const myArrowFunction = (parts: Parts) => ({
...parts,
someExtraPropertyWithoutError:'Why no report?:('
});
const DoesntShowError: FunctionType = myArrowFunction;
那么那里发生了什么?貌似是两个一模一样的函数,一个是箭头函数,一个是普通函数,为什么是箭头函数就没有错误呢?相同的参数,相同的 return 类型,相同的对象 returned.
关键区别在于,当我们定义箭头函数时,其 return 语句 NOT 上下文绑定到部件。 TypeScript 无法知道它要用在什么地方。所以它为其 return 类型生成一个形状,然后继续。
然后我们将它分配给 DoesntShowError
这需要我们分配给定类型的函数。而箭头函数满足了这个要求。我想就这些了,希望对你有帮助。