如何 return 传入类型的嵌套类型

How to return a nested type of a type that was passed in

假设我有一个类型 Person,其中包含他们的姓名、年龄和他们所有朋友的列表。

type Person = {
  name: string;
  age: number;
  friends: Person[];
}

然后说我有一个函数getFriendsWithSameAge。这个函数只需要 age 属性来做它需要做的事情。因此,不是将 Person 作为参数,而是将 MinimalPerson 作为参数,即:

type MinimalPerson = {
  age: number;
  friends: MinimalPerson[];
}

export function getFriendsWithSameAge(person: MinimalPerson) {
  return person.friends.filter(friend => friend.age === person.age);
}

这很好,因为 getFriendsWithSameAge 在输入参数方面非常灵活。您可以传入任何类型的 Person 对象,只要它至少定义了 agefriends。这是使用 GraphQl 时非常常见的场景。

问题来自 return 类型。此代码抱怨:

const person: Person = { name: 'John', age: 32, friends: [...] }

const friend = getFriendsWithSameAge(person)[0];
const name = friend.name; // error, function call destroys typing, doesn't know what name is

我希望我可以通过保留传入的类型然后 return 像这样使用泛型来解决这个问题:

export function getFriendsWithSameAge<T extends MinimalPerson>(person T): T['friends'] { // obviously doesn't work
  return person.friends.filter(friend => friend.age === person.age);
}

但我似乎不知道如何输入 return 类型。

编辑:我上面尝试的解决方案工作得很好。我的问题是,如果 T 可以为空,T['friends'] 不起作用,这是我为了这个问题而遗漏的细节。

Typescript Playground

实际上,在我的操场上,您的解决方案有效:TypeScript Playground [更新]