首页 > 解决方案 > 如何在 TypeScript 的函数定义中用子类型替换类型?

问题描述

interface Parent {
    name: string;
}

interface Child extends Parent {
    name: string;
    text: string;
}

function myFunction(text: string, target: Child): Child {
    target.text = text;
    console.log(target);
    return target;
}

const testChild: Child = {
    name: 'test',
    text: 'sample',
};

declare type FunctionType = (text: string, target: Parent) => Parent;

const func: FunctionType = myFunction;

func('newText', testChild);

此代码会导致错误,因为 FunctionType 等待具有 Parent(而不是 Child)作为参数和结果之一的函数。有没有办法让它与 Parent 的直系后代一起工作(就像 Child 一样)?

什么时候可能有用?假设我们有一个 Angular 组件,它接受简单的 slim 项目(比如我们的 Parent)和处理函数,但是我们想给这个组件一个 Child 项目和相应的处理函数(在我们的例子中是 myFunction)。所有组件的内部功能仅涉及与父相关的字段。我知道可以在 Angular 中为父组件的类创建一个子类并覆盖属性。但是为每个新的“子”类型创建一个新的组件或类会很痛苦。这只是一个例子。

我的一般问题是如何定义不仅接受父接口,还接受所有子接口(不列出子接口)的函数类型?

实际上我正在尝试实施基本的替代原则:对父母有用的东西应该对孩子有用。

标签: angulartypescript

解决方案


我想你可以使泛型使其工作,这似乎是你的情况下要走的路:

declare type FunctionType<T extends Parent = Parent> = (text: string, target: T) => T;

const func: FunctionType<Child> = myFunction;

操场

示例显示它仅适用于 的后代Parent,因为T extends Parent

操场


推荐阅读