Creating generic classes and functions in javascript ES06 - javascript

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.

Related

Using TypeScript Generics with Feature Checks [duplicate]

This question already has an answer here:
Is it possible to use the generic type to determine runtime functionality?
(1 answer)
Closed 2 years ago.
I am working with new and legacy pieces of UI and for a new feature that is rolling out, am using a feature toggle to decide which piece of the UI to show. The back-end, for the new feature now returns a different model so, throughout my code base, I have to account for this by creating V2 versions of existing methods/properties.
Throughout my code, there is a lot of this:
let someCollection: ModelV1 | ModelV2;
this.featureEnabled
? someCollection = someCollection as ModelV2
: someCollection = someCollection as ModelV1;
With the usage of TypeScript, I would like to create a generic function that would return to me whichever type I ask for and would abstract the feature check.
Another example is when I use the feature check to set a specific version of a property to a specific version of an array:
if (this.featureEnabled) {
this.someCollectionV2 = this.usersV2.filter(user => user.selected);
} else {
this.someCollection = this.users.filter(user => user.selected);
}
It's cumbersome to have this spread out over my code and it feels like a code-smell. How can I optimize this and make it more functional?
The OOP way to handle this would be to define an interface which has all of the functionality that depends on whether the feature is enabled. Then your main class stores an instance of a feature class which is either enabled or disabled. The main class only needs to check in one place -- where it creates and stores the feature instance -- and after that it never needs to check again because both classes have the same interface.
In my opinion this is the way to go as it resolves all of the typescript issues and also removes lots of if statements and unnecessary branching. We don't even need to store the featureEnabled boolean because we don't need it. Here's a dummy setup:
interface DependentFunctions {
doSomething(): number;
}
class MyClass {
private _handler: DependentFunctions;
constructor(featureEnabled: boolean) {
if ( featureEnabled ) {
this._handler = new V2Class();
} else {
this._handler = new V1Class();
}
}
exampleMethod() {
const num = this._handler.doSomething();
}
}
class V2Class implements DependentFunctions {
doSomething() {
return 2;
}
}
class V1Class implements DependentFunctions {
doSomething() {
return 1;
}
}
Playground Link
If you want to instead tackles typescript issues directly, then you can make use of type guards and assertion functions.
Some Examples

return multiple functions in Dart

I want to return various functions as the javascript object.
payments(auth_user).create();
payments(auth_user).delete(1);
to do this in javascript, look like this:
function payments(auth_user) {
return {
delete(id) {
//
}
}
}
But in Dart... How to do it?
The Dart way is to create a class that implements .create and .delete, and have payments return an instance of that class. There are no "anonymous classes" in Dart, as you can pretend in JavaScript.

Is there a pattern in JavaScript for loosely coupled objects.

I'm relatively new to JavaScript so apologies if this type of question is an obvious one.
We have an app which uses etcd as its way to store data. What I'm trying to do is implement a way of swapping or alternating between different backend data stores (I'm wanting to use dynamodb).
I come from a C# background so if I was to implement this behaviour in an asp.net app I would use interfaces and dependancy injection.
The best solution I can think of is to have a factory which returns a data store object based upon some configuration setting. I know that TypeScript has interfaces but would prefer to stick to vanilla js if possible.
Any help would be appreciated. Thanks.
Interfaces are "merely" a static typing measure to implement polymorphism. Since Javascript doesn't have any static type system, it also doesn't have interfaces. But, it's a highly polymorphic language in itself. So what you want to do is trivial; simply don't write any interfaces as part of the process:
function StorageBackend1() { }
StorageBackend1.prototype.store = function (data) {
// here be dragons
};
function StorageBackend2() { }
StorageBackend2.prototype.store = function (data) {
// here be other dragons
};
function SomeModel(storage) {
this.storage = storage;
this.data = {};
}
SomeModel.prototype.saveData = function () {
this.storage.store(this.data);
};
var m1 = new SomeModel(new StorageBackend1),
m2 = new SomeModel(new StorageBackend2);
m1.saveData();
m2.saveData();
Using TypeScript and actual interfaces gives you the sanity of a statically type checked language with fewer possible surprises at runtime, but you don't need it for polymorphism.
I come from Delphi / C# etc. And interface are just a pain in the but.
Javascript is so much nicer..
With javascript interfaces are not needed, just add the method.
eg.
function MyBackend1() {
this.ver = 'myBackEnd1';
}
function MyBackend2() {
this.ver = 'myBackEnd2';
this.somefunc = function () { console.log('something'); }
}
function run(backend) {
console.log(backend.ver);
//below is like an interface supports
if (backend.somefunc) backend.somefunc();
}
run(new MyBackend2());
//lets now use backend1
run(new MyBackend1());

Generics in Typescript - Undefined T

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.

Convert from Javascript to Typescript

How would I convert this function from Javascript to Typescript?
var ToggleSwitch = this.ToggleSwitch || (function () {
//Code
}
I know the var ToggleSwtich part can be written as export class ToggleSwitch {}, but I'm not sure about the rest of the line.
If you write a module, you'll end up with nearly identical code...
module ToggleSwitch {
}
Modules can be extended in TypeScript. The only difference is the compiler will know whether the module is already declared or not, which saves you the test.
To take this example further, here is an example with ToggleSwitch declared twice, with different contents. You'll notice that you can access all the contents. This can be split across multiple files:
module ToggleSwitch {
export class a {
go() {
alert('a');
}
}
}
module ToggleSwitch {
export class b {
go() {
alert('b');
}
}
}
var a = new ToggleSwitch.a();
var b = new ToggleSwitch.b();
a.go();
b.go();
Typescript is supposedly a superset of Javascript, so inherently, any Javascript should be valid Typescript.
Because TypeScript is a superset of JavaScript, most valid JavaScript is valid TypeScript too. In this case, your code (after adding a missing parenthesis at the end) is valid TypeScript and valid JavaScript.

Categories

Resources