Reputation: 5204
I'm converting some JS to TS, something like this:
class User {
constructor({ name, age }) {
this.name = name
this.age = age
}
// … + methods
}
I was hoping with TypeScript it would be able to infer the properties on User
, or there would be some way to avoid duplicating the shape of the constructor options object shape and the class shape. However, my attempt of getting TypeScript to infer the class shape from the options did not work:
type UserOptions = {
name: string
age: number
}
class User {
constructor(options: UserOptions) {
this.name = options.name // Property 'name' does not exist on type 'User'.
this.age = options.age // Property 'age' does not exist on type 'User'.
// or Object.assign(this, options), neither works
}
}
const user = new User({ name: 'Alice', age: 42 })
console.log(user.name, user.age) // Property 'name' does not exist on type 'User'.
I note that it's able to infer the shapes correctly if I use an object factory function instead of a class
:
type UserOptions = {
name: string
age: number
}
function User(options: UserOptions) {
return Object.assign({}, options)
}
const user = User({ name: 'Alice', age: 42 })
console.log(user.name, user.age)
Is there some way to tell TypeScript to infer the properties on a class User
from UserOptions
, or vice-versa?
I feel like I shouldn't need to manually duplicate each property definition from UserOptions
onto User
.
Something like the first example in this blog post: https://fettblog.eu/low-maintenance-types-typescript/
Upvotes: 1
Views: 409
Reputation: 33091
Here you have other solution:
interface User {
name: string
age: number
}
class User {
constructor(options: User) {
this.name = options.name
this.age = options.age
}
}
const user = new User({ name: 'Alice', age: 42 })
console.log(user.name, user.age) // Property 'name' does not exist on type 'User'.
Upvotes: 3