microsoft / microsoft/TypeScript

Infer method name for parameter decorator

Aperta
#30,102 7 commenti 5 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Needs Investigation
Lingua principale
Go
Stelle
111k
Fork
14.3k
Merge medio
2g 4h
PR unite (30g)
132

Descrizione

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;
    };
}

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia riproducendo gli esempi di decorator nel TypeScript Playground collegato, inclusa la definizione di InjectLike e il relativo riferimento a __playground.ts. Traccia come vengono inferiti il nome del metodo generico, l’indice del parametro e il tipo target; il lavoro è completato quando @Parameter() genera un errore su another_method(), mentre l’uso valido di @Inject viene accettato e il mismatch del costruttore contrassegnato viene rifiutato.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
compilers
Tipo di issue
Bug
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
30/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.