如何在结构化对象中为嵌套函数编写类型?

时间:2019-04-16 09:17:07

标签: typescript typescript-typings

我正在尝试为bodyheaderfooter编写类型,但是找不到访问它的方法。通常,在对象分解时会遇到这类问题。

bodyheaderfooter中我得到了错误: ” const body:任何。 属性“ body”在类型“ {}”上不存在。”

interface ModalProps {
  onClick: () => void;
 
}

const Modal: React.FunctionComponent<ModalProps> = props => {
  useContext(ModalContext);
  const [isOpen, setIsOpen] = useState(false);
  const [content = {}, setContent] = useState({});
  const show = (content = {}) => {
    const { body, header, footer } = content;
    if (!body && !header && !footer) {
      setContent({ content });
    } else {
      setContent({ body, header, footer });
    }
    setIsOpen(true);
  };

我试图将其插入界面,但没有成功:

interface ModalProps {
  onClick: () => void;
     content: {
     body: any
     }
 
}

也尝试过:

const { body, header, footer }: {body: any, header: any, footer: any} = content;

但收到错误消息:“类型'{}'缺少类型'{{body:any; header:any; footer:any;}':body,header,footer”的以下属性”

任何提示将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:2)

现在,content函数中的show类型为{},因为您没有告诉TypeScript有什么不同,而这就是从参数default可以推断出的全部内容({{1 }})。类型{}没有{},等等。

您需要告诉TypeScript body是什么。我有点想知道您想要content是什么,但您可能遵循以下原则:

content

那么interface Content { body?: string; header?: string; footer?: string; content?: Content; } 将是:

setContent

function setContent(content: Content) { // ... } 将是:

show

但是,使const show = (content: Content = {}) => { const { body, header, footer } = content; if (!body && !header && !footer) { setContent({ content }); } else { setContent({ body, header, footer }); } }; 必须处理setContent必须处理的同一件事似乎有点奇怪(检查是否有show,{{1 }}和body值或仅一个header值)。重载footer可能会更好。

答案 1 :(得分:1)

我相信问题是您在显示功能content上的默认const show = (content = {}) => {

这可能导致内容为空对象。这就是为什么您收到“类型'{}'上不存在属性'body'”的原因。打字稿推断body可能不存在于对象content中。

如果您不打算不带参数调用show,则只需删除默认值即可。另一方面,如果要键入显示功能,则可以创建以下界面:

type RawContent = String;
interface ContentWithHeaderAndFooter {
 header: any;
 body: any;
 footer: any;
}
type Content = RawContent | ContentWithHeaderAndFooter;
const show = (content: Content) => {...}

我相信这将涵盖您所使用的所有情况,但是对我来说,这有点过头了,我只需删除show函数的默认值即可。