Generics in Typescript - Undefined T - javascript

Having a problem with Typescript's Generics where the type is undefined in the scope of the generic function or class. I can't find any documentation on this though I would assume it is by design. Is there a way to achieve what I am trying to, type-safely?
function test<T>() {
return new T();
}
class TestClass<T> {
public build(): T {
return new T();
}
}
Link to Play:
http://www.typescriptlang.org/Playground/#src=function%20test%3CT%3E()%20%7B%0A%09return%20new%20T()%3B%0A%7D%0A%0Aclass%20TestClass%3CT%3E%20%7B%0A%09public%20build()%3A%20T%20%7B%0A%09%09return%20new%20T()%3B%0A%09%7D%0A%7D%0A

TypeScript generics (unlike other languages like C#) are compile time only. So you cannot use them in runtime positions e.g. new T.
Is there a way to achieve what I am trying to, type-safely
Pass the constructor explicitly. e.g.
class TestClass<T> {
public build(x:{new ():T}): T {
return new x();
}
}
Here x:{new ():T} I am saying that x is something that when called with new gives an instance of T.

Related

Declaring a module for a JavaScript Proxy in Typescript

I have something like this:
function createProxy ( configObj ) {
//...some code
return new Proxy({}, {
get: ( target, name ) => {
// ...does things
return Reflect.get(target, name);
},
set: function(target, name, value){
// ...does things
return Reflect.set(target, name, value);
},
}
}
I have to use "new" keyword for utilizing this function and this is how I use it:
const proxy = new createProxy({ someConfig: string })
proxy.foo = 'bar'
And I have declared this module like this:
declare module 'create-proxy' {
declare class createProxy {
constructor(config: { someConfig?: string })
[ index: string ]: string
}
export { createProxy }
}
And I have no type errors. But...
I have two concerns about this (I am new to Typescript module declaration, my typing can be totally wrong, and that is exactly what I need help about. I have read all the related Typescript docs but couldn't solve it on my own. I just need an experienced person to show me the way),
1- [index: string]: string seems too generic to me and my initial thought was "I think I should define the types of get and set methods of proxy somewhere in my declaration to be able to shape the type of indexable properties. I just feel it needs something more but I am not really experienced declaring modules and I can't point my finger at the problem.
2- What this module exports is actually a function that I need to call with the new keyword but what I am declaring is a class. That is because I have tried declaring it as a function but then I would get the type error saying that this function does not have a constructor (Because I am calling it with the new keyword when I am utilizing the function). I feel this is off, too.
Could you give me a hand here, please? Am I too confused or on the right path?
typescript 3.8.3

Using JsConstructor to deal with multiple constructors

I have a class with two constructors:
#JsType
public class Dog implements Animal {
String name;
public Dog() {
this.name = "Scooby Doo";
}
public Dog(String name) {
this.name = name;
}
}
I get the following error when I run gwt compile [With GWT-dev 2.8]
[ERROR] Constructor 'Dog(String)' can be a JsConstructor only if all constructors in the class are delegating to it.
I have been trying to work through this error, with not much success. I am not sure how to delegate to the other constructor.
Any help is very much appreciated!
Thanks!
Alas, JavaScript can't handle multiple constructors! You get one and only one.
There are some things you can do to pretend to have more than one - you can check the incoming data, and assign sane defaults:
#JsConstructor
public Dog(#JsOptional String name) {
if (name == null) {
name = "Scooby Doo";
}
this.name = name;
}
You have to be careful of types here if your two constructors do not use the same types in the same position - judicious use of instanceof might work (just be aware that for JS objects you are using JS instanceof, not java!). Another option lets you be more flexible, but again, no overloaded methods - factory methods:
public static Dog withName(String name) {
return new Dog(name);
}
public static Doc defaultImpl() {
return new Dog();
}
#JsIgnore
public Dog() {/*...*/}
#JsIgnore
public Dog(String name) {/*...*/}
Another idea on the same theme would be to create a JsType builder. This is a bit less idiomatic for JS.
Finally, you could consider the dreaded "options object", where your one constructor takes a single Object with properties, or a JsPropertyMap<Any> holding all the possible values, then check nullness and types inside the giant constructor. I avoid this personally - this is one of the terrible things I'm hoping to avoid by writing Java in the first place.

Creating generic classes and functions in javascript ES06

I'm from java background. I use Generics in java in following way:
class ApiResponse<T> {
T data;
T getData(){
return T;
}
}
I'm unable to use generics in javascript ES06. I wanna know whether it's possible or not creating generic classes?
JavaScript is a dynamically typed language and it doesn't have any generics. You can write a normal function/method, it will work for all types.
P.S. Use Typescript if want to code like you do in Java.
How do you like this, Elon Musk? Pure js, no typeflow/typescript
class BaseClass {
hello = function () {
console.log('hello!');
}
}
function GenericClass(T, Base) {
return class extends Base {
field = new T();
}
}
class DerivedFromGeneric extends GenericClass(String, BaseClass) {
greet = function() {
this.hello();
console.log('greetings ', this.field);
}
}
let i = new DerivedFromGeneric();
Javascript in itself doesn't provide any syntax to support generic classes. But it's possible using:
Flow
or
Typescript
Let me show an example of using generic class using Flow in javascript ES06:
export class ApiResponse<T> {
data: ?T = null
}
You can use Typescript for this purpose.
https://www.typescriptlang.org/docs/handbook/generics.html
Javascript doesn't have strict typing so there is no need for Generics because all variables can be assigned to any type at any time.

How to protect functions which are called with different contexts from breaking?

I'm fairly new to javascript and now I learned how calling functions with a context works.
Here is a simple example that poses a question in my head. Lets say we have this example:
var myObj = {
bar: function() {
console.log("Lets got to the bar!");
}
}
/* how can this be protected from errors,
* if a passed object doesn't contain bar */
function foo()
{
this.bar();
}
foo.call(myObj);
Now, how can foo be protected of breaking? In some OOP language (lets say Java) this would be implemented lets say via an interface. So in that case if the object being instantiated hasn't implemented the interface method, the compiler would through an error so the compiler protects the code/program from being faulty (in this case of course).
public interface MyInterface
{
public void bar();
}
public class MyClass implements MyInterface
{
public void bar()
{
System.println("Lets go to the bar");
}
}
MyInterface m = new MyClass();
m.bar(); // if bar isn't implemented the compiler would warn/break
Note: I'm not that good in Java so sorry for any syntax or other errors, but I hope you get the point.
So to sum up, as I see that in both cases in both languages one can achieve polymorphism, right? Now if so for the Javascript example, how can one protect it from breaking, are there any patterns or tricks? Does typeof this.bar === function work? If so, who guarantees the SW quality if the programmer forgets this, I'm asking this kind of question because Java has the compiler to warn the programmer about the mistake, does JS have something similar, some quality check tool?
Javascript is a dynamic interpeted* language. There isn't a compiler step to check references. Some tools (jsline) and IDEs (VS, Webstorm) can perform some design-time checks for you, but there's no true type safety. This is largely seen as a feature, not a bug.
There's an array of tricks to work around this (.hasOwnProperty, typeof x === 'function', storing self references, context binding) but mostly, if you want a type safety, you want a different language.
My recommendation is Typescript. It has a Java/C-like syntax, with some familiar OOP features, like classes, interface (and thus, sane polymorphism) and generic types, and transpiles to javascript in moments.
If you use a constructor to create your object you can use Javascript's builtin class member ship checking features. An example is below.
class MyClass {
bar() { console.log("Lets got to the bar!")}
}
function foo() {
if ( this instanceof MyClass ) {
this.bar();
}
else {
console.log('this is not a member of the MyClass');
}
}
foo.call(new MyClass);
Be warned that Javascript's type checking is horribly unreliable and you probably should not use it. If your object contains the same prototype anywhere in it's prototype chain as the class you are testing it for membership in, instanceof will return true.
Quick and dirty duck typing example
This will throw if you give it an object without the properties you are checking for, but you get the idea.
class MyClass {
constructor() {
this.feathers = 'white';
this.feet = 'webbed';
}
bar() { console.log("Lets got to the bar!")}
}
function foo() {
if (
this.hasOwnProperty('feathers') &&
this.hasOwnProperty('feet') &&
this.feathers === 'white' &&
this.feet === 'webbed'
)
{
this.bar();
}
else {
console.log('this is not a member of the MyClass');
}
}
foo.call(new MyClass);

In Typescript, can a method exist only on a subclass?

I have an inheritance hierarchy in a typescript application that resembles the following:
class A {
someProp: any;
constructor(someObj: any){
}
}
class B extends class A {
constructor(someObj: any){
super(someObj);
}
public doStuff(){
console.log("doing stuff!");
}
}
In a second file, I attempt to call methods on the subclass after instantiating it like so:
var instanceB: A;
...
instanceB = new B(someObj);
instanceB.doStuff(); // produces error symbol cannot be resolved, it is probably located in an inaccessible module
So what am I doing wrong? As far as I understand prototypal inheritance in JavaScript, the method will be searched for in the hierarchy of regardless of where it is defined.
As a workaround, I've added an abstract method in the base class, and then I provide the implementation in the subclass. The problem with this is that I need to be able to swap one subclass for another depending on the application state. And to me, it seems unnecessary to define a method on the parent class that all subclasses need not implement.
This doesn't work because instanceB is declared to be of type A and not the subtype B.
You can execute methods that belong to B, if instanceB is indeed an instance of B, by using a type guard:
var instanceB: A;
...
instanceB = new B(someObj);
if (instanceB instanceof B) {
instanceB.doStuff(); // no more error
}
Or by asserting instanceB to be of type B:
// no more error, but will throw an error when instanceB is not B
(instanceB as B).doStuff();

Categories

Resources