TypeScript: вывод свойств класса из конструктора (параметры) или наоборот

#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'.

 

https://www.typescriptlang.org/play?ssl=1amp;ssc=1amp;pln=16amp;pc=83#code/C4TwDgpgBAqgzhATgeTMAlgewHZygXigG8AoKKbAQwFsIAuKOYRdbAczKkrfooFdqAIyQkAviRIBjADaU4eeEmKdJOJoj6TgmRAApMaLLgaKUhtQEpl5csAAW6OADoqtAlAMY1LmtAD0flAACogGSKBQAOSuEJFQACaYEHjYmMBQEAAejuk4UKCQUaaRTpy2Ds7c0ISeRpU8UAHBoZCIEZFVcYnJFGkZ2Uwe2Png0JHFpTaNgTpQyIIAVhBaTnJw6GzYuvaOADQe5rgW 9gQ6PZKAO46ANZwnOLiUmrpfAiI7qeXsO 6RBS BiRACC0nQkli yqDAALAAmKCiCwSVS4TDSCBOaSYNi6N5IHy0fb4xCrHhWJohMJtEBRGJdJIpPpZHJDEaFcbvEpAA

Я отмечаю, что он может правильно выводить фигуры, если я использую функцию фабрики объектов вместо 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)
 

https://www.typescriptlang.org/play ?#code/C4TwDgpgBAqgzhATgeTMAlgewHZygXigG8AoKKbAQwFsIAuKOYRdbAczKkrfooFdqAIyQkAviRIAzPtgDGGHLASIAYtgAUmNFlwN4SVAtwBKYp0QRgfRNijJBAKwjyAdJThx0bDUVEAaKC0jOGMxCVkcJig ZQIlJDV1IgoaXgByAEEAG3RZCDSA7l4AFgAmKFFQkgjcTCyIFyzMNnUYpBcqWgC2xDceYyA

Есть ли какой-нибудь способ указать 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'.