TypeScript - using recursive generics properly [duplicate] - javascript

This question already has answers here:
How do I declare object value type without declaring key type?
(2 answers)
Closed 12 months ago.
I am trying to use recursive generics in a way I can get a lot of help from editor.
Here is an example:
interface ServiceEndpointNode {
self: string;
context?: Record<string, ServiceEndpointNode>
}
const ServiceEndpoints: ServiceEndpointNode = {
self: 'BASE_URL',
context: {
songs: {
self: 'GET_SONGS',
context: {
getSong: {
self: 'GET_SONG',
},
getContributors: {
self: 'GET_CONTRIBUTORS',
}
}
}
}
}
This works properly and the structure is strict, but I don't got help from the editor. For example I want help like:
ServiceEndpoints.context.songs.context.getsong.self
But because I only told the typing that the context should be a string I don't really receiving help about the traversable object. I guess I need to be include some generics or something, but don't know how to achieve that. :(
So I want to have to maintain this strict structure, yet get help from the editor for all the possible routes, keys, etc.

Now you can use Optional chaining in TypeScript simplify as shown below. So that typescript compiler will expect NULL | underfined
console.log(ServiceEndpoints.context?.songs.context?.getSong?.self);
// OUTPUT: "GET_SONG"

Related

what does this symbol mean in the typescript '< >'? [duplicate]

This question already has answers here:
What does angle brackets “<>” mean in function declaration in Typescript?
(3 answers)
Closed 1 year ago.
I am a beginner in Typescript and JavaScript trying to understand a code. I encounter "< >" at several places in the code, as described in an example below.
(value: any, manager: ManagerBase<any>|undefined)
Why we use "< >" in typescript.
Thanks
ManagerBase is a generic type. It uses a parameter for a type in its definition (not present in the code you posted).
Let's say we have the type Sample<T> defined like this:
type Sample<T> = T[];
This makes Sample<T> an alias of the type "array of values of type T". The type Sample<number> is the same as number[], Sample<string> is the same as string[] and so on. Sample<any> is the same as any[].
In the code you posted, the type ManagerBase<any> uses any as the value of T.
Read about "generics" in the TypeScript handbook.
This symbol is used to specify the type when using generics.
See the official TypeScript-Documentation for further information: https://www.typescriptlang.org/docs/handbook/generics.html

Best approach to avoid naming collisions in object with javascript [duplicate]

This question already has answers here:
Is the underscore prefix for property and method names merely a convention?
(6 answers)
Closed 2 years ago.
Lets say I have an object with a getter and a setter.
const obj = {
a: 0,
get a(){
return this.a;
}
}
I would get an error Maximum call stack size exceeded at Object.get a [as a]. I could name the a variable something different but then it gets confusing after a while.
I could prefix it with an underscore or something like this:
const obj = {
_a: 0,
get a(){
return this._a;
}
}
I was wondering if there is an industry standard for handling this? Is using underscores not the right approach because they are symbolic of other things? What is the recommended approach for handling this or is it one of those things that is up to the developer?
I just don't want to go down the path of doing this the wrong way and can't really find a definitive answer on the matter.
Thanks.
Your first example doesn't work, because the getter named a will end up being the only property on your object. When you call this.a you're actually calling the getter again and so you end up with a stackoverflow.
Using _ as prefix for underlaying variables is perfectly fine. This actually lines up with other languages.

Javascript API syntax help - const { uport, MNID } [duplicate]

This question already has answers here:
What is the difference between const and const {} in JavaScript
(4 answers)
Closed 4 years ago.
So while I was making my react native app, I tried to use an API from
https://github.com/uport-project/react-native-uport-connect and there is a syntax that I've yet to understand.
May I know what does const { uport, MNID } mean from this code
import configureUportConnect from 'react-native-uport-connect'
const { uport, MNID } = configureUportConnect({
appName: 'uPort Demo',
appAddress: '2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG',
privateKey:'<PRIVATE_KEY>',
})
Im quite new to this and this code is placed on a seperate js file and im trying to export const { uport, MNID } so I could use it in my Components and im not sure if it's a variable, object or some js syntax. Thank you!
This is called destructuring, and it means you are assigning your variables, not to the object that the function returns, but to the individual properties of that object, specifically the properties at the keys uport and MNID. The alternative syntax would be to say const variableName = // etc... and then you would access the properties like: variableName.uport.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring

Accessing 'this' inside Typescript raw function [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 4 years ago.
I have an Angular 6 app that uses the excellent ngx-charts framwork to display charts. This charting component lets me specify a tooltip formatting function like so:
<ngx-charts-bar-vertical [xAxisTickFormatting]="dateTickFormatting" >
</ngx-charts-bar-vertical>
And then define the formatting function in the parent component class:
dateTickFormatting(val: string): string {
return val.toUpperCase();
}
My problem happens when I try to access values in the parent component class from this formatter function:
public testVar: string = 'This is a test variable';
dateTickFormatting(val: string): string {
console.log(this.testVar);
return val.toUpperCase();
}
In this case, testVar will be undefined.
I understand that the 'this' reference is lost because ngx-charts is referencing dateTickFormatting as a 'raw' function. Is there a way to preserve a reference to the parent classes' this, barring modifications to the charting framework?
You should use arrow functions
If you do
public testVar: string = 'This is a test variable';
dateTickFormatting = (val: string): string => {
console.log(this.testVar);
return val.toUpperCase();
}
It will use the correct this and work.
I recommend reading a bit about arrow functions https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Extending functionality in TypeScript [duplicate]

This question already has answers here:
Closed 10 years ago.
The community reviewed whether to reopen this question 5 months ago and left it closed:
Original close reason(s) were not resolved
Possible Duplicate:
How does prototype extend on typescript?
I am currently learning TypeScript, and would like to know how it is possible to add functionality to existing objects. Say I want to add an implementation for Foo to the String object. In JavaScript I would do this:
String.prototype.Foo = function() {
// DO THIS...
}
Understanding that TypeScript classes, interfaces and modules are open ended led me to try the following, without success
1. Reference the JavaScript implementation from TypeScript
JavaScript:
String.prototype.Foo = function() {
// DO THIS...
}
TypeScript:
var x = "Hello World";
x.Foo(); //ERROR, Method does not exist
2. Extend the interface
interface String {
Foo(): number;
}
var x = "Hello World";
x.Foo(); //Exists but no implementation.
3. Extend the class
class String {
Foo(): number {
return 0;
}
}
// ERROR: Duplicate identifier 'String'
As you can see from these results, so far I have been able to add the method via an interface contract, but no implementation, so, how do I go about defining AND implementing my Foo method as part of the pre-existing String class?
I have found the solution. It takes a combination of the interface and the JavaScript implementation. The interface provides the contract for TypeScript, allowing visibility of the new method. The JavaScript implementation provides the code that will be executed when the method is called.
Example:
interface String {
foo(): number;
}
String.prototype.foo= function() {
return 0;
}
As of TypeScript 1.4 you can now also extend static members:
interface StringConstructor {
bar(msg: string): void;
}
String.bar = function(msg: string) {
console.log("Example of static extension: " + msg);
}

Categories