【问题标题】:Why I can't use Omit on AsyncProps of react-select?为什么我不能在 react-select 的 AsyncProps 上使用 Omit?
【发布时间】:2020-06-23 11:50:31
【问题描述】:

我一直在尝试将组件 SelectSearchResult 包裹在来自 react-selectAsyncSelect 周围。我希望我的自定义组件的道具与AsyncSelect 几乎相同,但有一些例外。

import AsyncSelect, { Props as AsyncSelectProps } from "react-select/async";

// works, but Props allows all properties
type Props = AsyncSelectProps<{ label: string; value: string }>;

const SelectSearchResult = (props: Props) => {
    return <AsyncSelect {...props} />;
};

我以为我只需要省略我不想要的键。

type Props = Omit<AsyncSelectProps<{ label: string; value: string }>, "loadOptions">;

但是,当我检查 Props 时,它现在具有以下格式,我不知道它为什么会变成这种形状。

type Props = {
  [x: string]: any;
  [x: number]: any;
}

【问题讨论】:

    标签: reactjs typescript react-select


    【解决方案1】:

    经过大量搜索,我发现问题实际上在于定义AsyncProps 的方式,因为在其主体中找到了一个索引签名,这使得ExcludeOmit 无法正常工作。

    为了说明问题:

    // This type accepts the known keys `a` and `b` as strings and anything 
    // else with unknown keys
    type MyType = {
        a: string;
        b: string;
        [key: string]: any; // index signature
    };
    
    type MyTypeWithoutA = Omit<MyType, "a">;
    
    // I expected the object below to complain for the fact, that "b" is not defined
    // but it doesn't happen
    const obj: MyTypeWithoutA = {}; 
    

    我找到的解决方案是首先创建一个不带索引签名的派生类型MyType,然后创建一个替代版本的Omit

    type KnownKeys<T> = {
        [K in keyof T]: string extends K ? never : number extends K ? never : K
    } extends { [_ in keyof T]: infer U } ? U : never;
    
    // K is the union of keys I want to omit from the known keys of T
    type OmitKnownKeys<T, K extends string> = Omit<Pick<T, KnownKeys<T>>, K>;
    
    

    重写代码

    type MyTypeWithoutA = OmitKnownKeys<MyType, "a">;
    
    const obj: MyTypeWithoutA = {}; // error, b is not defined (what I wanted)
    

    重要提示:此解决方案适用于我的特定情况,但实际上它会从您的类型中删除索引签名,使其不太灵活,换句话说,您无法传递任何匹配的参数索引签名。如果要保留索引签名,请检查 this version

    来源:12

    【讨论】:

      【解决方案2】:

      您可以使用never 类型和&amp; 运算符。例如:type Props =AsyncSelectProps<{ label: string; value: string }> & {loadOptions: never };

      当有人尝试调用Props.loadOptions 时,它会返回never,并且永远不能分配给任何类型,因此在下次使用时会引发错误。

      【讨论】:

        猜你喜欢
        • 2022-12-07
        • 1970-01-01
        • 2021-07-02
        • 1970-01-01
        • 1970-01-01
        • 2010-11-14
        • 2015-07-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多