export default null ; class A { protected constructor ( ) { } } class B extends A { } new A ( ) ; new B ( ) ; type Shoe = { purpose : string ; } ; class BalletFlat implements Shoe { purpose = 'dancing' ; } class Boot implements Shoe { purpose = 'woodcutting' ; } class Sneaker implements Shoe { purpose = 'walking' ; } type ShoeCreator = { create ( type ) : BalletFlat ; create ( type ) : Boot ; create ( type ) : Sneaker ; } ; let Shoe = { create ( type ) { switch ( type ) { case 'balletFlat' : return new BalletFlat ( ) ; case 'boot' : return new Boot ( ) ; case 'sneaker' : return new Sneaker ( ) ; } } } ; Shoe . create ( 'balletFlat' ) ; Shoe . create ( 'boot' ) ; Shoe . create ( 'sneaker' ) ; class RequestBuilder { protected data : object | null = null ; protected method : 'get' | 'post' | null = null ; protected url : string | null = null ; setMethod ( method ) { return new RequestBuilderWithMethod ( ) . setMethod ( method ) . setData ( this . data ) ; } setData ( data ) { this . data = data ; return this ; } } class RequestBuilderWithMethod extends RequestBuilder { setMethod ( method ) { this . method = method ; return this ; } setURL ( url ) { return new RequestBuilderWithMethodAndURL ( ) . setMethod ( this . method ) . setURL ( url ) . setData ( this . data ) ; } } class RequestBuilderWithMethodAndURL extends RequestBuilderWithMethod { setURL ( url ) { this . url = url ; return this ; } send ( ) { } } new RequestBuilder ( ) . setMethod ( 'get' ) . setData ( { } ) . setURL ( 'foo.com' ) . send ( ) ; interface BuildableRequest { data ? : object ; method : 'get' | 'post' ; url : string ; } class RequestBuilder2 { data ? : object ; method ? : 'get' | 'post' ; url ? : string ; setData ( data ) { return Object . assign ( this , { data } ) ; } setMethod ( method ) { return Object . assign ( this , { method } ) ; } setURL ( url ) { return Object . assign ( this , { url } ) ; } build ( this ) { return this ; } } new RequestBuilder2 ( ) . setData ( { } ) . setMethod ( 'post' ) . setURL ( 'bar' ) . build ( ) ;