Typescript: Implementing a generic interface -


consider following generic interface:

interface extractor<t> {   extractcandidate(): t;   process(candidate: t): t; } 

conceptually, each extractor implementation responsible extracting particular kind of object datasource. consumer of extractor can extract candidate object using extractcandidate() or, given candidate, perform further processing on more refined version of object using process().

now, let's implement extractor class myclass, so:

class myclass {   a: string;   b: string; }  class myextractor implements extractor<myclass> {   extractcandidate() {     //some dummy logic     return new myclass();   }   process(candidate) {     //some dummy logic     let res = new myclass();     res.a = candidate.a;     return res;   } } 

now let's instantiate myextractor , use it:

let myextractor = new myextractor(); let processed = myextractor.process('blah'); 

question 1: why not generate compile-time error? based on definition of extractor interface, expect compiler not allow me call myextractor.process() instance of myclass, or @ least structurally compatible.

question 2: how can enforce desired behavior? need assert candidate parameter of myextractor.process() of type myclass?

i suspect has typescript's structural typing system but, after reading some related questions , faq, i'm still not sure how applies here.

my typescript version 2.1.4.

the code posted myextractor has following signature process method:

process(candidate: any): myclass 

the reason haven't specified type candidate default any.
compiler won't complain because satisfies candidate: t (as any can t).

if change code to:

process(candidate: myclass) {     ... } 

then for:

let processed = myextractor.process('blah'); 

you'll get:

argument of type '"blah"' not assignable parameter of type 'myclass'

you can avoid using --noimplicitany flag cause compiler complain about:

process(candidate) {     ... } 

saying:

parameter 'candidate' implicitly has 'any' type


edit

candidate isn't allowed "anything else", allowed any (and that's default), reason for example overloading:

process(candidate: string): myclass; process(candidate: myclass): myclass; process(candidate: any) {     ... } 

Comments