#Mapped keyof types to class
89 messages · Page 1 of 1 (latest)
don't use loops / reduction functions to copy / transform key/values from an object
because it's not that easy to type
because you'd need to declare an empty object first
but then you wouldn't be able to assign keys/values to an empty object
if you make it partial, then you still need to remove the partial before retning it, etc.
so it's not that easy
I recommend using Object.entries(), Array.prototype.map(), and Object.fromEntries()
so that's for the assignment part
about this part, [key: keyof T]: T[key];, you can just use implements to implement an interface
just like in regular OOP
Preview:```ts
interface ID {
id: string
}
export class BaseClientEntity implements ID {
id!: string
constructor(baseClientEntity: {id: string}) {
Object.assign(this, baseClientEntity)
}
}```
but that means you'll have to repeat some code
@agile cape
one thing you could do, is use an abstract class that you will inherit from
that way, you'll have a separate ID type, while not having to repeat those fields
Preview:```ts
abstract class ID {
id!: string
constructor(id: {id: string}) {
Object.assign(this, id)
}
}
export class BaseClientEntity extends ID {
constructor(baseClientEntity: {id: string}) {
super(baseClientEntity)
Object.assign(this, baseClientEntit
...```
like so
that's how I've been doing that, I guess
but you need to repeat everything from the interface into the every version of it
and there's a lot of it
a decent chunk of it is generated code
so it's not always BaseClientEntity extends ID
hence my 2nd solution
but yeah, there is no easy fix
maybe if you provide more context I'm sure we can work out a better solution
but yeah, mixing raw types and classes in TS is always a bit of a pain
I basically have a bunch of plain interfaces generated
I want to "augment" them into classes
and combining types/interfaces together is easier and provides as much safety
just create classes in the first place
not possible
no reason to use interfaces as DTO in TS, you can use clases to achieve the same thing
again, a decent chunk of it is generated by a code generation tool
fair
but less ergonomics
I guess I can redesign my APIs
I feel like a main issue with TypeScript that many people haven't noticed is that typescript usually maintains a good separation of values and types
except for classes
they're values
but also types
typescript usually maintains a good separation of values and types
don't really see what you mean by that
except for classes
they're values
but also types
the fact an object is a class doesn't matter at all in TS
only it's "general shape" matters
structural typing in a nutshell
const n = 123
console.log(n) // works
type Bleh = Foo<n> // doesn't work
type t = { foo: string }
console.log(t) // doesn't work
type Bleh = Foo<t> // works
class c {}
console.log(c) // works
type Bleh = Foo<c> // also works
right, there is a difference between a JS object you can use (value)
and a TS type that will be erased and that can only be used to check your code
however, there are ways to create types from values
like typeof
yeah
const foo = 123;
type Foo = typeof foo;
// ^?
do types live in the same namespace as values
would something like
const Foo = 123;
type Foo = typeof Foo;
work
I know that
just tried it, it apparently works
I was just asking this as an example to ask if it's possible for the types and values to have a same name
if you think about it, that's what classes are
they declare a type with the same name as the value
if you think about it, that's what classes are
they declare a type with the same name as the value
right, the same name can be used both to create new instances and to refer to the type of an instance
and to refer to the type of the class itself, have to use typeof
ok, so from what I see here I shouldn't try to augment interfaces to classes
but just use classes outright
or interfaces
I'm just basing my designs off how discord.js and similar libraries are built
they cache heavily
especially if you want to use classes instances for their class "properties" (instanceof + methods + inheritance)
and it's generally a mess
I just want a way to implement an interface without repeating myself too much
right, it becomes more about keeping track of where the data is, and in what state it is, if it needs to be re-validated or not, etc.
it is possible
again, type merging the interface with the class
so can't really be checked properly by the compiler
but still, much of what is here is for internal library code
I basically built up an internal library to do exactly that automatically for me