首页 > 解决方案 > 派生的泛型类不能分配给打字稿中的基泛型类

问题描述

我有一张存储各种元素的地图。定义如下:

const map = new Map<string, IComponent<IBase>>();

我想用这张地图来存储IComponent<IBase>,IComponent<INumber>等的实例IComponent<IText>

基本接口定义如下:

// base interface
interface IBase {}
// base component type
export type IComponent<T extends IBase> = React.FC<T>;

现在我想添加一个NumberComponent

// derived interface
interface INumber extends IBase {
    someNumber: number;
}
// some component
const NumberComponent: IComponent<INumber> = (props) => {
    return (
        <div>{props.someNumber}</div>
    );
}

我曾经map.set('number', NumberComponent)将它存储到地图上,但我得到了

Argument of type 'FC<INumber>' is not assignable to parameter of type 'FC<IBase>'.
  Types of parameters 'props' and 'props' are incompatible.
    Type 'PropsWithChildren<IBase>' is not assignable to type 'PropsWithChildren<INumber>'.
      Property 'someNumber' is missing in type 'PropsWithChildren<IBase>' but required in type 'INumber'.

我知道我可以用来map.set('number', NumberComponent as IComponent<IBase>)转换类型。但是,我不想使用as. 还有其他方法可以解决这个问题吗?

ts 操场上的演示

标签: reactjstypescript

解决方案


这是可能的。你只需要超载你的Map

import React from 'react'

interface IBase { }

export type IComponent<T extends IBase> = React.FC<T>;

interface INumber extends IBase {
  someNumber: number;
}


type MapOverloads = Map<string, IComponent<IBase>> & Map<string, IComponent<INumber>>
const map:MapOverloads  = new Map<string, IComponent<IBase>>();


const NumberComponent: IComponent<INumber> = (props) => {
  return (
    <div>{props.someNumber}</div>
  );
}

const BaseComponent: IComponent<IBase> = (props) => {
  return null
}

map.set('number', NumberComponent)

map.set('base', BaseComponent)

操场

主要思想被@jcalz的这个答案无耻地窃取了

但是,因为map是可变的,并且我假设您希望它是可变的,所以getter.


const expectNumber = map.get('number') // IComponent<IBase> | undefined

PS由于逆变,您无法分配IComponent<INumber>IComponent<IBase>


推荐阅读