#typescript #class #type-inference
#typescript #класс #вывод типа
Вопрос:
Я конвертирую некоторые JS в TS, что-то вроде этого:
class User {
constructor({ name, age }) {
this.name = name
this.age = age
}
// … methods
}
Я надеялся, что с помощью TypeScript он сможет выводить свойства User
, или будет какой-то способ избежать дублирования формы объекта параметров конструктора и формы класса. Однако моя попытка заставить TypeScript вывести форму класса из параметров не сработала:
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'.
Я отмечаю, что он может правильно выводить фигуры, если я использую функцию фабрики объектов вместо 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)
Есть ли какой-нибудь способ указать TypeScript выводить свойства class User
из UserOptions
, или наоборот?
Я чувствую, что мне не нужно вручную дублировать каждое определение свойства из UserOptions
onto User
.
Что-то вроде первого примера в этом сообщении в блоге: https://fettblog.eu/low-maintenance-types-typescript /
Комментарии:
1. Добавьте строку
interface User extends UserOptions {}
, и слияние объявлений вступит в силу2. @AluanHaddad Вау, спасибо, что работает, но я не совсем понимаю, почему. Отправьте это как ответ, и я отмечу его как таковой.
3. typescriptlang.org/play ? #код/…
4. Рад помочь. Я бы добавил ответ, но @captain-yossarian уже написал ответ, который применяет ту же технику и более элегантно, хотя и без объяснений. Руководство по языку объясняет, что здесь происходит: typescriptlang.org/docs/handbook/declaration-merging.html
5. @AluanHaddad ваш на самом деле является лучшим решением для моей конкретной проблемы, потому что Он сохраняет тип пользовательского класса (т. Е. Данные методы) и тип параметров (данные) отдельно.
Ответ №1:
Здесь у вас есть другое решение:
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'.