Javascript - 创建一个可以将解构对象属性作为参数但可能缺少某些属性的通用函数

Javascript - Creating a universal function that can take destructured object properties as arguments but where some properties might be missing

我想找到一种方法,如何将不同的对象传递给同一个函数,并让该函数只处理给定对象中存在的输入。 具体来说,我正在传递不同的 Angular 组件,并且正在解构对象属性。

export function filterVisualData({data, playersOn, typesOn, resultsOn, toBeRemoved, teamsOn, xGOn, shotsOn}) {
  return data.filter(d => {
    const result = d.success ? 'Successful' : 'Unsuccessful';
    const players = playersOn.length === 0 || (playersOn.length > 0 && playersOn.includes(d.player_name));
    const types = typesOn.length === 0 || (typesOn.length > 0 && typesOn.includes(capitalizeAllWords(d.type)));
    const results = resultsOn.length === 0 || (resultsOn.length > 0 && resultsOn.includes(result));
    const removed = !toBeRemoved.map(p => p.time).includes(d.time);
    const shots = shotsOn.length === 0 || (shotsOn.length > 0 && shotsOn.includes(d.type));
    const xG = xGOn.length === 0 || (xGOn.length > 0 && d.xG < Math.max(...xGOn));
    const teams = teamsOn.length === 0 || (teamsOn.length > 0 && teamsOn.includes(d.team_name));
    return players && types && results && removed && shots && xG && teams;
  });
}

问题是某些组件缺少某些属性,我收到此错误

TS2345: Argument of type 'this' is not assignable to parameter of type '{ data: any; playersOn: any; typesOn: any; resultsOn: any; toBeRemoved: any; teamsOn: any; xGOn: any; shotsOn: any; }'.   Type 'ShotChart' is not assignable to type '{ data: any; playersOn: any; typesOn: any; resultsOn: any; toBeRemoved: any; teamsOn: any; xGOn: any; shotsOn: any; }'.     Property 'typesOn' is missing in type 'ShotChart'.

你可以传递任何对象而不会引起 Typescript 的抱怨,方法如下:

export function filterVisualData(obj: any) {

    const { data, playersOn, typesOn, resultsOn, toBeRemoved, teamsOn, xGOn, shotsOn } = obj

    return data.filter(d => {
        const result = d.success ? 'Successful' : 'Unsuccessful';
        const players = playersOn.length === 0 || (playersOn.length > 0 && playersOn.includes(d.player_name));
        const types = typesOn.length === 0 || (typesOn.length > 0 && typesOn.includes(capitalizeAllWords(d.type)));
        const results = resultsOn.length === 0 || (resultsOn.length > 0 && resultsOn.includes(result));
        const removed = !toBeRemoved.map(p => p.time).includes(d.time);
        const shots = shotsOn.length === 0 || (shotsOn.length > 0 && shotsOn.includes(d.type));
        const xG = xGOn.length === 0 || (xGOn.length > 0 && d.xG < Math.max(...xGOn));
        const teams = teamsOn.length === 0 || (teamsOn.length > 0 && teamsOn.includes(d.team_name));
        return players && types && results && removed && shots && xG && teams;
    });
}

所以你在编译时不会出错,但在运行时仍然会出错。如果您没有通过 playersOn,那么您将遇到 Cannot read length of undefined 崩溃。您需要为每个值实施故障保护。

您还可以利用 TypeScript 中内置的接口和 Partial

export interface IData {
    success: boolean;
    player_name: string;
    type: string;
    time: string;
    team_name: string;
}
export interface IBaseArgs {
    data: IData[] , 
    playersOn: <TypeHere>, 
    typesOn: <TypeHere>, 
    resultsOn: <TypeHere>, 
    toBeRemoved: <TypeHere>, 
    teamsOn: <TypeHere>, 
    xGOn: <TypeHere>, 
    shotsOn: <TypeHere>
}

export function filterVisualData<T extends Partial<IBaseArgs>>(obj: T) {
  const {data, playersOn, typesOn, resultsOn, toBeRemoved, teamsOn, xGOn, shotsOn} = obj;
  return data.filter(d => {
    const result = d.success ? 'Successful' : 'Unsuccessful';
    const players = playersOn.length === 0 || (playersOn.length > 0 && playersOn.includes(d.player_name));
    const types = typesOn.length === 0 || (typesOn.length > 0 && typesOn.includes(capitalizeAllWords(d.type)));
    const results = resultsOn.length === 0 || (resultsOn.length > 0 && resultsOn.includes(result));
    const removed = !toBeRemoved.map(p => p.time).includes(d.time);
    const shots = shotsOn.length === 0 || (shotsOn.length > 0 && shotsOn.includes(d.type));
    const xG = xGOn.length === 0 || (xGOn.length > 0 && d.xG < Math.max(...xGOn));
    const teams = teamsOn.length === 0 || (teamsOn.length > 0 && teamsOn.includes(d.team_name));
    return players && types && results && removed && shots && xG && teams;
  });
}

使用 Partial 将使所有键成为可选的,并且函数将接受缺少键的对象。您还将获得 IntelliSense。