microsoft / microsoft/TypeScript

Infer method name for parameter decorator

未关闭
#30,102 7 条评论 5 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

Needs Investigation
主要语言
Go
星标
111k
派生
14.3k
平均合并
2 天 4 小时
30 天内合并 PR
132

描述

TypeScript Version: 3.3.3
Tried with @next (3.4.0-dev.201xxxxx) ? NO

Search Terms: type:issues infer method name parameter decorator

Code

declare function Method():
{
    (t: any, m: 'method'): void;
}

declare function Parameter():
{
    (t: any, m: 'method', i: number): void;
}

class Play
{
    @Method() // err
    public another_method ( @Parameter() /* NO ERROR */ test: number ): void
    {
        throw new Error('Not yet implemented');
    }
    @Method()
    public method ( @Parameter() test: number ): void
    {
        throw new Error('Not yet implemented');
    }
}

Expected behavior: @Parameter() should error just as @Method() when applied to another_method() because the m parameter is typed "method" (which should reduced the set of method). i.e method name should be enforced.

Actual behavior: No error

Playground Link: https://typescript-play.js.org

Use case :

I crafted a type that filters method names with the nth parameters iff that parameters is of the given type T.

See KeysToTypedNthParameter definition here

let hash = {
    a( _0: string, _1: string ) {},
    b( _0: string, _1: number ) {},
    c( _0: number, _1: number ) {},
    d( _0: number, _1: string ) {},
}

let string_0: KeysToTypedNthParameter<0, string, typeof hash>; // "a" | "b"
let string_1: KeysToTypedNthParameter<1, string, typeof hash>; // "a" | "d"
let number_0: KeysToTypedNthParameter<0, number, typeof hash>; // "c" | "d"
let number_1: KeysToTypedNthParameter<1, number, typeof hash>; // "c" | "d"

Later, I used that type to infer method name for my parameter decorator - @Inject - in the excerpt below, I marked the ONLY line that should error and why (but both lines actually error)

class Test
{
    public blatantly!: boolean;
}

class Play
{
    public method(
        @Inject({ type: Test })
        @Inject({ type: Number }) // err (construtor mismatch instance type)
        test: Test,
    ): void
    {
        throw new Error( 'Not yet implemented' );
    }
}
Play;

Here is @Inject decorator definition and complete code -

const Inject: InjectLike = void 0 as unknown as InjectLike;

interface InjectLike
{
    <
        C extends ConstructorLike,
    >
    ({}: { type: C }): {
        <
            // FIXME : not enough to infer the method name - see ./__playground.ts#
            M extends ( T extends ConstructorLike ? never : KeysToTypedNthParameter<I, InstanceType<C>, T> ),
            I extends number,
            T,
        >
        ( target: T, member: M, index: I ): void;
    };
}

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

首先在链接的 TypeScript Playground 中复现 decorator 示例,包括 InjectLike 定义及其对 __playground.ts 的引用。跟踪泛型方法名、参数索引和目标类型的推断方式;完成的标准是:@Parameter()another_method() 上报错,而有效的 @Inject 用法被接受,并且标记的构造函数不匹配被拒绝。

由索引模型根据 Issue 内容生成。

评估

技术栈
typescript
领域
compilers
Issue 类型
缺陷
难度
5/5
预计耗时
一周以上
活跃度
停滞
描述清晰度
基本清楚
新手友好度
30/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。