Typescript 类型';{name:string;}&;拾取<;TProps,排除<;“TProps的按键”;名称“&燃气轮机&燃气轮机';不可分配给类型';TProps&x27;
我正在尝试创建一个可以在没有提供道具的情况下设置道具的 如果需要,我可以提供该代码,但它附带了一些使代码复杂化的代码,实际上与我遇到的错误没有任何关系 因此,我创建了一个MVCE,它以更清晰的方式再现了问题:Typescript 类型';{name:string;}&;拾取<;TProps,排除<;“TProps的按键”;名称“&燃气轮机&燃气轮机';不可分配给类型';TProps&x27;,typescript,Typescript,我正在尝试创建一个可以在没有提供道具的情况下设置道具的 如果需要,我可以提供该代码,但它附带了一些使代码复杂化的代码,实际上与我遇到的错误没有任何关系 因此,我创建了一个MVCE,它以更清晰的方式再现了问题: interface RequiredProps { name?: string; } const setDefaults = <TProps extends RequiredProps>(props: TProps) => { const {
interface RequiredProps {
name?: string;
}
const setDefaults = <TProps extends RequiredProps>(props: TProps) => {
const {
name: nameProp,
...rest
} = props;
const newProps: TProps = {
name: (nameProp != null) ? nameProp : "Alice",
...rest
};
return newProps;
};
我得到了一个错误:
因此,我用抓取我知道应该存在的字段,并将其余字段放入…rest
然后我构造newProps
组合我默认的字段和…rest
问题是,在这一点上,我得到了错误:
Type{name:string;}&Pick
不能分配给TypeTProps
对我来说,读作“TProps,不包括name属性,加上name字段,不能分配给TProps”,这让我有点困惑
我想知道它是否不喜欢name
现在是string
而不是string?
。问题是,string
可分配给string?
,但我还是尝试修改代码
const newProps: TProps = {
name: ((nameProp != null) ? nameProp : "Alice") as string | undefined,
...rest
};
但正如预期的那样,这没有什么区别
我注意到在错误消息中,它说类型是{name:string;}
,而不是{name?:string;}
,因此我对代码进行了更改,尝试解决这个问题
const newRequiredProps: { name?: string } = {
name: (nameProp != null) ? nameProp : "Alice"
};
const newProps: TProps = {
...newRequiredProps,
...rest
};
错误消息现在显示了“更正确”的类型,但基本上保持不变
Type{name?:string;}&Pick
不能分配给TypeTProps
我确实发现了一个有效的方法,那就是使用as
强制输入:
const newProps: TProps = {
name: (nameProp != null) ? nameProp : "Alice",
...rest
} as TProps;
但这感觉就像我只是在掩盖打字问题,而不是真正解决它
有没有办法让类型系统理解我要做的事情,而不是强迫它接受类型?编译器很难验证泛型类型上复杂的条件类型操作。只要您确信不会发生这样疯狂的事情,您正在执行的类型断言是完全可以接受的:
type PossiblyBob = { name?: "Bob" };
const possiblyBob: PossiblyBob = Math.random() < 0.5 ? {} : { name: "Bob" };
setDefaults(possiblyBob);
这或多或少是一样的(只要props.name
实际上没有设置为未定义的值)。但是,缺少类型错误是一种技巧。forObject.assign()
返回其输入类型的名称,即。最终,它们可能会返回Object.assign()
的返回类型,然后您也会遇到相同的类型断言问题
所以我想我的建议是离开类型断言并继续
希望有帮助;祝你好运 感谢您的关注和解释。
type PossiblyBob = { name?: "Bob" };
const possiblyBob: PossiblyBob = Math.random() < 0.5 ? {} : { name: "Bob" };
setDefaults(possiblyBob);
const setDefaults: TProps = <TProps extends RequiredProps>(props: TProps) => {
const newProps = Object.assign({ name: "Alice" }, props);
};