Angular 14 Form Control - Inheriting recursively types from interface - angular-forms

I was wondering if anyone managed use complex interfaces to take advantage of the new typed FormControl and avoid boilerplate code on components.
I manage to export a 1-level-only interface with:
interface ISimple {
a: number; b: string; c: Date
}
export type AsFormControls<T> = {
[K in keyof T]: FormControl<T[K]>;
}
and then declaring my form in my component as
form: FormGroup<AsFormControls<ISimple>>;
Some of my simple forms were just plug and play, very useful, but when I have something like the following I can't figure out how to proceed, because I need the a FormGroup type for properties that contain properties.
interface INotSoSimple {
d: {
e: string;
f: Date;
}
}
Could there be a way to modify this interface for it to work with the new Form Controls? Any leads?

Related

Is it possible to have a field with a generic type that refers to the actual runtime type of the containing class?

I'm fiddling around with this code where I have a base class Node which can be extended:
open class Node
class SubNode : Node()
Now, I have a Behavior class that can be attached to a node, and when this attachment happens, the behavior object is invoked:
open class Behavior {
fun attach(node: Node) {
println("Behavior was attached to a node")
}
}
open class Node {
var behavior: Behavior? = null
set(value) {
field = value
value.attach(this)
}
}
This works, but could this be generified in such way that the type of the attach method would always refer to the actual type of the attached Node? For instance, if the Behavior class was extended like this:
open class Behavior<NodeType: Node> {
open fun attach(node: NodeType) {
}
}
class SubBehavior : Behavior<SubNode>() {
override fun attach(node: SubNode) {
}
}
I've tried various ways of setting up the types in Node class, but can't figure any other way than passing the actual subclass type to the base class (which seems rather cumbersome):
open class Node<SubType: Node> {
var behavior: Behavior<SubType>? = null
}
class SubNode : Node<SubNode>()
Is there a way to do this in any other way?
I think what you need are self types, which don't exist in Kotlin (at least, not yet).
Using recursive generics like you did is the most common way around the problem.
That said, I have trouble understanding your use case here for intertwining these 2 classes together this way. Like how is behaviour used inside your node, etc.

Koin - How to generify Singleton creation?

I have a class InteractorCache<T> that I would like to inject in different places using Koin.
I would like to create a singleton instance of that class based on the type T. So if I have 10 types T, I would like 10 different singletons.
So far I managed to do the above with the following code (this is an example with only 2 types, A and B):
val interactorAModule = module {
factory {
InteractorA(get())
}
}
val aCache = module {
single(named("A")){
InteractorCache<List<A>>()
}
}
val interactorBModule = module {
factory {
InteractorB(get())
}
}
val bCache = module {
single(named("B")){
InteractorCache<List<B>>()
}
}
This works but there is a lot of repetition as I have to create a new cache module (aCache, bCache) every time I create a new type. I would like to be able to do something like this instead:
val cacheModule = module{
single<T>{
InteractorCache<T>()
}
}
so there is only 1 declaration that works for any type T.
Is there a way to do this in Koin?
Although this is late but the idea of making generic or T a singleton is bad idea, when you declare a class singleton it will run a single instance, so runtime error would be InteractorCache() is incompatible or mismatched to InteractorCache() as the first class you would assign the T for example the class A InteractorCache() it would be fixed instance of A and cannot anymore assign to class B.

Kotlin data classes contains open functions

I was reading kotlin official tutorial, Under the data class topic, I came up with a following point.
If a supertype has the componentN() functions that are open and return compatible types, the corresponding functions are generated for the data class and override those of the supertype. If the functions of the supertype cannot be overridden due to incompatible signatures or being final, an error is reported;
My Questions are,
1) What is componentN() functions ?
2) Does the data class override the open function automatically ?
3) Is following code correct ?
open class SuperDataClass {
open fun componentN() {
println("from super class")
}
}
data class DataClassExample (var name: String): SuperDataClass() {
//
}
1) What is componentN() functions ?
They are operator functions corresponding to the properties in their order of declaration.
Example:
data class Person(name: String, age: Int)
the class above will have a component1 and a component2 function, allowing the access through destructuring declaration to name and age, in that order.
Take in consideration that componentN function is just to reference 1st, 2nd, 3rd, ..., Nth component. The componentN function itself is never generated.
2) Does the data class override the open function automatically ?
In data class, you are extending from Any class, you aren't overriding automatically any function. componentN functions are generated at compile time.
3) Is following code correct ?
open class SuperDataClass {
open fun componentN() {
println("from super class")
}
}
data class DataClassExample (var name: String): SuperDataClass() {
//
}
Yes, it will compile and will run correctly. But this is only because, as I said before, componentN isn't generated for data classes.
However, in this case a component1 is generated for the property name of DataClassExample. As the quote of the documentation you posted says: if you try this code, you will have an error.
open class SuperDataClass {
open fun component1() {//<-- note this
println("from super class")
}
}
data class DataClassExample (var name: String): SuperDataClass() {
//
}
The specific error is:
[DATA_CLASS_OVERRIDE_CONFLICT] Function 'component1' generated for the data class conflicts with member of supertype 'SuperDataClass'

To create an object (of some class) in a listener

I'm creating a script and have troubles.
Is it possible to create an object (of some class) from within a listener?
I tried it but I get an error: ``class not found''.
I want to do something like:
class ONE {
class_ONE_code
}
class TWO {
object o = alloc(ONE)
}
I need this to create a new listener when I execute another listener.
What you wish to do is certainly possible. Most likely you have a syntax error in your code. For example, your implementation of class TWO is invalid since a member variable like "o" cannot be initialized in the member declaration section of the class code. This can only be done within a class method, as illustrated in the example code below.
class One
{
void DoClassOneAction(Object self)
{
OKDialog("Class One action executed.");
}
}
class Two
{
Object oneInstance;
void DoClassTwoAction(Object self)
{
if (!oneInstance.ScriptObjectIsValid())
oneInstance = Alloc(One);
oneInstance.DoClassOneAction();
}
}
void main()
{
Object twoInstance = Alloc(Two);
twoInstance.DoClassTwoAction();
}
main();
Note that the coding requirements for DM script classes differ somewhat from those of other languages that support objects. You may want to review details in the Scripting > Objects section of the DM on-line help (accessed via Help > Search… menu item).

Typescript error when using interface from module as field within class

I am working on providing a type definition file for fabric.js. The general structure is shown in the following sample:
declare module fabric {
export interface Canvas {
selectionBorderColor: string;
selectionColor: string;
...
}
var Canvas: {
new (): Canvas;
}
}
This pattern allows me to use fabric.Canvas in a 'interface-like' way, so that variables are associated with the fabric.Canvas interface. At the same time it allows me to call "static members" (such as the constructor of fabric.Canvas).
But this leads to a problem when using a field of interface 'fabric.Canvas' within a class. The following sample shows such an case:
This problem only occurs when placing the interface within a module, otherwise everything works fine.
Any solutions for this problem?
There is some type confusion because you have an interface and a field with the same name - I know this is common in the lib.d.ts file, but I don't think it is a good practice when writing new TypeScript code. It seems to be something of a necessity for defining existing code.
If you rename var Canvas to var MyCanvas (or anything else) your code works.
I tend to prefix my interfaces with an I, for example ICanvas - but this isn't a TypeScript convention (yet).
declare module fabric {
export class Canvas {
selectionBorderColor: string;
selectionColor: string;
}
}
class MyClass {
canvas: fabric.Canvas;
}