简体   繁体   中英

Extending from an interface to add a new property results in "Type X is not generic"

export interface IOptionsPropsExtra extends IOptionsProps<IOptionListBelowProps> { delete: any}

export const SelectedChoiceItem: (optionProps: IOptionsPropsExtra<IOptionListBelowProps>) => React.ReactElement<any> =
    (optionProps: IOptionsPropsExtra<IOptionListBelowProps>) => {
        return (
            <Label className={styles.item}>
                {optionProps.item.name}
                <IconButton iconProps={{ iconName: 'Trash' }} onClick={optionProps.delete} />
            </Label>
        );
    };

I wrote the interface IOptionsPropsExtra to be able to pass an extra argument which is called delete and is a function, but in doing so I am getting:

Type "IOptionsPropsExtra" is not generic.

Is there something I am misunderstanding about interfaces and how to extends them? I thought extending is basic inheritance which allows you to inherit all of the properties of the interface so that you can add any new one on top of it, which is literally all I am doing. Why am I getting an error about it not being generic? Should it even be a generic type? It's clearly should not be given what I am trying to do plus isn't a generic something like any, which goes against what I am trying to do here?

The key problem is what do you want IOptionsPropsExtra to be:

  1. A non-generic intereface that is an extension of a specific IOptionsProps what always has IOptionListBelowProps as the value of its generic variable, ie the extension of IOptionsProps<IOptionListBelowProps>

  2. A generic interface that extends IOptionsProps and uses the same generic variable as that interface

The problem is you wrote the definition for 1, but used it as 2.

For 1 , you use your interface definition as a regular interface:

export const SelectedChoiceItem: (optionProps: IOptionsPropsExtra) => React.ReactElement<any> =
    (optionProps: IOptionsPropsExtra) => {
//...

For 2 , what I suppose you want to do , you leave the const as it is but define the interface as a generic one:

export interface IOptionsPropsExtra<T> extends IOptionsProps<T> { delete: any}

To be clear, a "generic" type is one that uses another type as a variable.

IOptionsPropsExtra is not a generic type because it can be completely resolved without providing any other type.

let IOptionsPropsExtra | null = null // works fine.

IOptionsProps is a generic type because it requires another type to be passed to it. You are doing that when you say IOptionsProps<IOptionListBelowProps> .

So you are locking your IOptionsPropsExtra type to be of type IOptionsProps with generic parameter type of IOptionListBelowProps .

What I think you intend is one of two things.

  1. You want the IOptionsPropsExtra to always extend IOptionsProps<IOptionListBelowProps> and no other type should ever be passed to IOptionsProps when you use your custom type. If this what you want then you have declared the type properly and you just use it like any other type without the <ParameterType> syntax.
(optionProps: IOptionsPropsExtra) => {
  1. Or you want the IOptionsPropsExtra to be generic, just like the type it extends. In that case, you need to declare it like as a generic, and forward the generic parameter to the type that it extends:
export interface IOptionsPropsExtra<T> extends IOptionsProps<T> {
    delete: any
}

And use it like this:

(optionProps: IOptionsPropsExtra<IOptionListBelowProps>) => {

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM