typescript 类型脚本泛型数组,find()方法,用于从输入元组中提取结果类型,

hivapdat  于 2022-12-01  发布在  TypeScript
关注(0)|答案(1)|浏览(253)

假设我有一个这样的小部件层次结构:

interface IBaseWidget {
  type: string;
}

interface IButton extends IBaseWidget {
  type: 'button';
  title: string;
}

interface ICheckbox extends IBaseWidget {
  type: 'checkbox';
  checked: boolean;
}

type IWidget = IButton | ICheckbox;
type IWidgetType = IWidget['type'];

我想写一个方法来查找给定类型的所有小部件。
如何键入此函数,以便它可以从输入数组中“提取”正确的成员类型?
基本上:

function findByType(widgets: IWidget[], type: IWidgetType) {
  return widgets.filter(x => x.type === type);
}

// How to make this IButton[] ?
const buttons = findByType([], 'button');

如果这是绝对通用的,那就更好了,因为我甚至不需要知道IWidget,但是元组变量是直接从输入数组类型中提取出来的。
我可以这样做:

const input: ({type: 'A'} | {type: 'B'} | {type: 'C'})[] = [];
const result = findByType(input, 'B'); // result: {type: 'B'}[]

沙盒:https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgJICE4GcIHVgAmA5hGMgN4BQyyYAngA4QBcyWYUoRA3JQL6VKoSLEQoMAVzBgA9iGQQAHpBAEsaTDnzFSFarUYtkAcgBGU2SGO8aYYGAA2R9pxA9+g4dHhI0AYQALCAQAa1MZRQVlCFV1DGw8QhIyKltDVmMEINDwxWt9LOCQiAJWcJknOBBeAUp6JjRtZOQAXg0LOWQAH39ssIjeevEm0gAVQ1bGpNIAbWMh4wBdXkoYCRAEO06YUAJ0OnGmAAoAd2mwLFZUEbAZxYAaAyYrm8OIAEo9GihSCSh5M46C4AOh2DhER0iLQAfMhFMChq0Wm0hu8aoIAPQY5AACRkJ1oMmQAFs4MVaAFgHF0B0QHdkAB+SgIOTsZDmaSsyY7VT7N5HO6PMy04xooA

34gzjxbg

34gzjxbg1#

我以这个excellent previous answer为灵感,设计了一个适合您的用例的改编版本:

interface IBaseWidget {
  type: string;
}

interface IButton extends IBaseWidget {
  type: "button";
  title: string;
}

interface ICheckbox extends IBaseWidget {
  type: "checkbox";
  checked: boolean;
}

type IWidget = IButton | ICheckbox;

type FilterWidgetByType<
  W extends IWidget,
  Type extends string
> = W extends any ? (W["type"] extends Type ? W : never) : never;

function findByType<T extends IWidget["type"]>(widgets: IWidget[], type: T) {
  return widgets.filter(
    (widget): widget is FilterWidgetByType<IWidget, T> => widget.type === type
  );
}

// How to make this IButton[] ?
const buttons = findByType([], "button");
const checkboxes = findByType([], "checkbox");

这里是TSPlayground链接。

相关问题