如何指示变量和数组的类型,我们确定变量的值在 Typescript 中的数组中?

How to indicate type of a variable and an array we know for sure that the value of the variable is in the array in Typescript?

提问人:Nguyễn Minh 提问时间:11/15/2023 更新时间:11/15/2023 访问量:80

问:

你们知道以某种方式指示变量的类型吗,我们确定这个变量的值在 Typescript 中的数组中?

例如,我想在选项卡栏上显示选项卡列表:

const TabsBar= ({tabs}: {tabs: string[]}) => {
    const [activeTab, setActiveTab] = useState<string>(tabs[0]) //the active tab by default is the first tab in array of tabs

    useEffect(() => {
        setActiveTab(tabs.find(tab => tab === activeTab))//give error Argument of type 'string | undefined' is not assignable                      
//to parameter of type 'string'. How to define type of "tabs" and "activeTab" so that the error disappear?
    }, [tabs, activeTab])
        
    ...
}

而且在选项卡具有这种形式的情况下,如何制作而不会出错?{id:number;title:string}tabs.find(tab => tab.id === activeTab.id)

谢谢!!!

javascript reactjs 数组 typescript react-native

评论


答:

0赞 Ale_Bianco 11/15/2023 #1

您可以使用 TypeScript 泛型来定义数组的类型和状态,并使用关键字来断言 的结果不会是 .tabsactiveTabasfindundefined

import { useState, useEffect } from 'react';

// Define a generic type for tabs that can be either string or an object with an `id` property
type Tab = string | { id: number; title: string };

const TabsBar = ({ tabs }: { tabs: Tab[] }) => {
    const [activeTab, setActiveTab] = useState<Tab>(tabs[0]);

    useEffect(() => {
        // Check if activeTab is a string or an object with an `id` property
        if (typeof activeTab === 'string') {
            // For string tabs, find the tab by directly comparing values
            setActiveTab(tabs.find(tab => tab === activeTab) as Tab);
        } else {
            // For object tabs, find the tab by matching the `id` property
            setActiveTab(tabs.find(tab => (tab as { id: number }).id === (activeTab as { id: number }).id) as Tab);
        }
    }, [tabs, activeTab]);

    // Rest of your component...

    return (
        <div>
            {/* Render your tabs here */}
        </div>
    );
};

export default TabsBar;
1赞 Gaël Courosse 11/15/2023 #2

如果你这样做:

const TabsBar= ({tabs}: {tabs: string[]}) => {
  const [activeTab, setActiveTab] = useState<string>(tabs[0]) 
  useEffect(() => {
    const result = tabs.find(tab => tab === activeTab);
    if (result) {setActiveTab(result))};
    }, [tabs, activeTab])
}

然后,它应该没问题,尽管它并没有完全回复您的请求。

否则,您必须在此处放置感叹号(非空断言运算符):

    tabs.find(tab => tab === activeTab)!
2赞 Mr. Nun. 11/15/2023 #3

你的具体问题与数组可能是空的这一事实有关,为了让 Typescript 像你一样,做 2 件事:

比方说是你的类型,也可能是。Tabstring

  1. 使用此语法告诉 TypeScript 数组中至少有一个元素。
   const TabsBar = ({ tabs }: { tabs: [Tab, ...Tab[]] }) => {
      // implementation
   }

2.处理返回 undefined 的情况。find

   ...
   useEffect(() => {
      const selected = tabs.find(...) //now selected is of type `Tab | undefined`
      if (!selected) throw Error("Unexpected tab") // this shouldn't happen
      // any future usage of `selected` would be Tab without undefined
      setActiveTab(selected)
   }