What is <T> in dynamic forms? - angularjs

Im following the Angular2 cookbook recipe for Dynamic Forms. It calls for
export class QuestionBase<T>{
value: T,
...
I cant seem to find out what the is doing in both spots. Any ideas?

Those are so called "Generics". You may just google for the term "generics", for example in combination with "typescript", in order to get a more detailed answer.
The quick version is:
with generics you do not care which type T is - as long as it is the same type everywhere you use it.
So an instance of
QuestionBase<String>
has to make sure that the property "value" is of type String

The T on the QuestionBase<T> stands for Type.
This means that whatever type you enter in the <> that is the type that value will have.
So,
If T = string:
export class QuestionBase<string>{
value: string,
If T = int:
export class QuestionBase<int>{
value: int,
If T = any:
export class QuestionBase<any>{
value: any,
If T = any[]:
export class QuestionBase<any[]>{
value: any[],

T here makes your class a template..which means your class can be of any type
while creating the object of QuestionBase you can say like below
var obj=new QuestionBase<string>();
now here your value property will be of string type.
Similarly
var obj=new QuestionBase<int>(); value property will of type int here.

Related

Jest SpyOn choose the correct overload

I do have a class that has 2 overloaded methods.
public static create<M extends Model>(
this: ModelStatic<M>,
values?: M['_creationAttributes'],
options?: CreateOptions<M['_attributes']>
): Promise<M>;
public static create<M extends Model>(
this: ModelStatic<M>,
values: M['_creationAttributes'],
options: CreateOptions<M['_attributes']> & { returning: false }
): Promise<void>;
in my unit test, I'm trying to use jest.spyOn to mock the first method however jest sees only the one that returns Promise<void>.
const mockInsightCreate = jest.spyOn(Insight, "create");
mockInsightCreate.mockReturnValue(Promise.resolve()); // here I need to return an object of type - Insight
Is there a way to instruct spyOn to pickup the first method that returns Promise<M> ?
import {
Model,
} from "sequelize-typescript";
...
export default class Insight extends Model<Insight> {
I know this question is old, but bellow is my answer for anyone facing the same issue who might stumble across it.
There is currently no way of instructing which overload signature spyOn should use. One solution would be to cast the value to whatever spyOn expects.
mySpy.mockReturnValue(Promise.resolve(myObj) as unknown as void);
mySpy.mockResolveValue(myObj as unknown as void);
However, I personally prefer avoiding coercing the typing system if possible. Another workaround that does not require any typing judo is to mock the entire method implementation.
mySpy.mockImplementation(() => Promise.resolve(myObj));

Unable to pass props when enum is used to define proptype

I am using React + Typescript.
In one of my component I have declared the interface as
enum PersonDept {
CIVIL = 'civil',
PRIVATE = 'private'
}
interface IPerson {
dept: PersonDept.CIVIL | PersonDept.PRIVATE
}
Now, If I've to use the person component anywhere else then I've to export the enum in order to pass dept prop type. Is there any way out there in which I can skip exporting the enum.
Also if I've to export the enum anyways, is the the right way to do so?
According to your types, the property dept accepts only the values of the enum PersonDept.
So yes, you have to use the enum and import it on every usage, that's the desired behavior and how it usually used.
Is there any way out there in which I can skip exporting the enum
One way is to not use the enum:
interface IPerson {
dept: 'civil' | 'private'
}
And a more hacky and not recommended way is to set the enum as a global variable, like attaching it to window:
// Don't do it, just know it is possible
window._IPreson = PersonDept

Why does TypeScript allow overloading return type as 'any' when implementing interfaces

I am trying to determine why TypeScript allows you to overload the return type of a function to the type 'any' from a more specific type when implementing an interface.
In my case I am working in Angular and am injecting the implemented class.
My environment:
Visual Studio 2017
Angular Version 1.5.5
TypeScript Version 2.1.5
The following code compiles without any issue:
export interface IFoo {
thing: (parameter: number) => string;
}
export class BarService implements IFoo {
public thing = (parameter: number): any => {
return { "whatever": parameter };
}
}
angular.module("FooBar").service("barService", BarService);
So now when I attempt to consume the IFoo interface and am expecting a string to be returned from the 'thing' function call the compiler actually allows it to happen!
export class Whatever {
public foo: IFoo;
public myString: string;
static $inject = ["barService"];
constructor(barService: IFoo) {
this.foo = barService;
this.myString = this.foo.thing(0);
}
}
It seems that TypeScript should fail to compile when the return type is overloaded with type 'any' because consumers of the interface are expecting a strongly typed object.
Here is what I have put together.
From https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.1:
All types in TypeScript are subtypes of a single top type called the
Any type. The any keyword references this type. The Any type is the
one type that can represent any JavaScript value with no constraints.
And also:
The Any type is used to represent any JavaScript value. A value of the
Any type supports the same operations as a value in JavaScript and
minimal static type checking is performed for operations on Any
values. Specifically, properties of any name can be accessed through
an Any value and Any values can be called as functions or constructors
with any argument list.
Playing around:
interface IPerson {
name: string
}
class Person implements IPerson {
name: any;
}
// Error
//class Person2 implements IPerson {
// name: number;
//}
const person: Person = new Person();
person.name = 3;
let x: number = 3;
x = <any>"hello"; // Works!
//x = "hello"; // Error
We can see in even a simple example above that any can be used to override the type system which follows the docs.
My belief is that this behavior is there to allow the flexibility of javascript's untyped (flexible) behavior.
I'm not an expert on Typescript but based on my understanding of any:
https://www.typescriptlang.org/docs/handbook/basic-types.html
We find this comment on that page:
"We want to opt-out of type-checking and let the values pass through compile-time checks."
So I'm guessing when the compilers sees any, it says "I will not confirm this type". Ergo this condition must be sufficient for the compiler to assume that the function has been implemented correctly.
I used to think of any as "accept anything" (which is does). But more precisely it means "Assume this is the type you want.", from what I've seen. So in this case the compiler assumes it is string for your convenience and allows the compile-time check to pass.
As i see it there are two places that you could expect TypeScript compiler to fail. BarService returning any and Whatever class assigning return value from thing() function to myString.
The compiler doesn't fail when you return any in your BarService because in TypeScript you can use any as a substitude for any/all Types. The type any in TypeScript is mainly thought of to make it easier to support old javascript libraries or code. Check the Any section here: https://www.typescriptlang.org/docs/handbook/basic-types.html. And yes can and is abused.
The compiler doesn't fail in your Whatever class because here you are using the interface that in fact does says that the thing() function returns a string. The compiler do not know about the BarService when compiling the Whatever class.

How do I get array item type in TypeScript using the Reflection API?

I have the following little class in TypeScript, with some public fields decorated:
class Company {
#dataMember
public name: string;
#dataMember
public people: Person[];
}
class Person {
// ...
}
By using reflect metadata, I can determine the types of Company properties name and people: they are the constructor functions String and Array, respectively, which is expected and logical.
My property decorator function:
function decorate(target: Object, propertyKey: string | symbol): void {
var reflectType = Reflect.getMetadata("design:type", target, propertyKey);
// ...
}
But how could I determine the type (constructor function) of array elements? Is it even possible? In the above example, it should be (a reference to) Person.
Note: I need the type reference before instantiation, and because of this, it is impossible to dynamically determine the type using array items: there are no array items, there isn't even an Array instance.
I don't think this is possible as of now. If you see the generated js file, for array of anything, it creates metadata with type as Array without any information on type.
__decorate([
dataMember_1.dataMember,
__metadata('design:type', Array)
], Company.prototype, "people", void 0);
For built-in types, one way I could think of solving this problem is to pass the type in the decorator itself and writing the custom logic in the decorator code.
#dataMember(String)
myProp: Array<String>
For Custom objects, most of the time when the decorator call is fired, the module is not fully loaded. So, one way is to pass the class name and parse it later.
#dataMember("People")
people: People[]

GQL db.Model default parameter value

I found it kinda troublesome or difficult to find exact example I wanted for GQL.
Given the following:
class Sample (db.Model):
name = db.StringProperty(required=True)
type = db.StringProperty(required=False)
How do I set default parameter value.Let's say, I want to set type parameter to the value of "new" when I do following:
Sample(name="Yeah").put()
What would be the format of setting the default parameter value for a class inherited db.Model ?
Just add "default" parameter in the definition of your type, like this:
class Test(db.Model):
Test = db.StringProperty(default="test")

Resources