javascript - 传入方法的动态 Typescript 类型

标签 javascript typescript

说我有

interface User {
    name: string;
    age: number;
}

interface Car {
    year: number;
    model: string;
}

interface Action<T> {
    assign<K extends keyof T>(key: K, value: T[K]): void;
}

这让我可以:

const userActions: Action<User> = ...;
const carActions: Action<Car> = ...;

userActions.assign('age', 1); // all good
userActions.assign('foo', 2); // error that `foo` does not exist
userActions.assign('age', 'foo'); // error that type string is not assignable to age

carActions.assign(...); // same behavior for car

现在我想创建可以传递给assign的辅助方法,例如:

const logAndAssign = (key, value): void;

我希望能够做到

userActions.assign(logAndAssign('age', 1));
// etc

所以我希望这些辅助方法 logAndAssign 获取传递给它们的类型。我怎样才能做到这一点?

最佳答案

您不能直接使用单个参数调用函数,您可以使用 applyapply 调用不是类型安全的并且调用 logAndAssign 将暗示您显式传递类型参数:

const logAndAssign = function <T, K extends keyof T>(key: K, value: T[K]): [K, T[K]] {
    console.log(`${key} ${value}`);
    return [key, value];
};
userActions.assign.apply(userActions, logAndAssign<User, 'age'>('age', 1));

更好的解决方案是替换 Action 上的 assign 函数,然后恢复它:

function withLogging<T>(a: Action<T>, doStuff: (a: Action<T>) => void) {
    let oldAssign = a.assign;
    // Replace the assign function with a logging version that calls the original
    a.assign = function <K extends keyof T>(key: K, value: T[K]): void {
        console.log(`${key} ${value}`);
        oldAssign.call(this, key, value);
    };
    try {
        doStuff(a);
    } finally {
        //Restore the original assign 
        a.assign = oldAssign;
    }
}
// Single call
withLogging(userActions, u => u.assign('age', 10));
// Multiple calls
withLogging(userActions, u => {
    u.assign('age', 10);
    u.assign("name", 'd');
});

关于javascript - 传入方法的动态 Typescript 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48292680/

相关文章:

javascript - 输入文本框只允许英文小写字母

javascript - 从多个组件更新服务数据 - Observable subscribe

angular - 在 Angular 中刷新 owl-carousel

javascript - 使用 sinon、mocha 和 SWC 对导出函数进行 stub 失败

typescript - 在 JavaScript 中使用 as 作为别名

javascript - .removeAttr ('style' ) 在 ipad 上似乎无法正常工作

javascript - 如何使用两点经纬度绘制行车路线路径

javascript - AWS Amplify 登录 `currentAuthenticatedUser` 在登录后返回 `User is not authenticated`

javascript - 如何获取 React tsx 中给定元素的坐标

javascript - Angular 5 - 返回另一个动态函数的函数