te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - How to use Proxy<T> with a different type than T as argument? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use Proxy<T> with a different type than T as argument? - Stack Overflow

programmeradmin4浏览0评论

I'm in a situation where I want to use Proxy, to "load balance" between a list of class.

A naive example of what I'm trying to do is the following :

class Foo {
    constructor(private msg: string) {}

    foo() {
        console.log(this.msg);
    }
}

// @ts-ignore
const proxy: Foo = new Proxy([new Foo('foo'), new Foo('bar')], {
    get: (o, key) => {
        const client = o[Math.floor(Math.random() * o.length)];
        console.log(client, key);
        return client[key];
    },
});
proxy.foo();

This "works". The problem is that I'm using typescript. And, due to the Proxy type definition we can't do something like

new Proxy<Foo>([new Foo(), new Foo()], handler)

as it produce the following error :

Argument of type 'Foo[]' is not assignable to parameter of type 'Foo'.

Is there a way to achieve this ; without loosing type checking ?

I'm in a situation where I want to use Proxy, to "load balance" between a list of class.

A naive example of what I'm trying to do is the following :

class Foo {
    constructor(private msg: string) {}

    foo() {
        console.log(this.msg);
    }
}

// @ts-ignore
const proxy: Foo = new Proxy([new Foo('foo'), new Foo('bar')], {
    get: (o, key) => {
        const client = o[Math.floor(Math.random() * o.length)];
        console.log(client, key);
        return client[key];
    },
});
proxy.foo();

This "works". The problem is that I'm using typescript. And, due to the Proxy type definition we can't do something like

new Proxy<Foo>([new Foo(), new Foo()], handler)

as it produce the following error :

Argument of type 'Foo[]' is not assignable to parameter of type 'Foo'.

Is there a way to achieve this ; without loosing type checking ?

Share Improve this question edited May 30, 2018 at 11:08 Niladri 5,9622 gold badges26 silver badges43 bronze badges asked May 30, 2018 at 10:56 Rémi RousseletRémi Rousselet 277k89 gold badges553 silver badges451 bronze badges 1
  • as works but may or may not satisfy "without loosing type checking" – KTibow Commented Dec 28, 2024 at 2:17
Add a ment  | 

3 Answers 3

Reset to default 8

You don't need to change the existing definitions, you can just augment them.

If you are using a module system, you need to redeclare the ProxyConstructor in global for it to work:

declare global  {
    interface ProxyConstructor {
        new <TSource extends object, TTarget extends object>(target: TSource, handler: ProxyHandler<TSource>): TTarget;
    }
}


const proxy: Foo = new Proxy<Foo[], Foo>([new Foo('foo'), new Foo('bar')], {
    get: (o, key) => {
        const client = o[Math.floor(Math.random() * o.length)];
        console.log(client, key);
        return client[key];
    },
});
proxy.foo();

A straightforward solution is to create a factory like this:

function balance<T>(instances: Array<T>): T {
  return new Proxy<any>({}, {
    get: (o, key) => {
        const client = instances[Math.floor(Math.random() * instances.length)];
        console.log(client, key);
        return client[key];
    },
  }) as T;
}

const proxy = balance([new Foo('foo'), new Foo('bar')]);
proxy.foo();

That way you have a reusable and typesafe balancer without promising any declaration.

You can edit Proxy type definition to allow a different type from it's parameter type.

interface ProxyConstructor {
    revocable<T extends object, S extends object>(
        target: T,
        handler: ProxyHandler<S>,
    ): { proxy: T; revoke: () => void };
    new <T extends object>(target: T, handler: ProxyHandler<T>): T;
    new <T extends object, S extends object>(target: S, handler: ProxyHandler<S>): T;
}
declare var Proxy: ProxyConstructor;

Then modify your Proxy usage to the following :

const proxy: Foo = new Proxy<Foo, Foo[]>([new Foo('foo'), new Foo('bar')], {
    get: (o, key) => {
        const client = o[Math.floor(Math.random() * o.length)];
        console.log(client, key);
        return client[key];
    },
});
发布评论

评论列表(0)

  1. 暂无评论