[英]typescript: automatically create getters for all of a constructor's named parameters
[英]Typescript: Create class via constructor passing in named parameters?
我有一個類,其中的構造函數定義了 3 個參數,這些參數都是可選的。 我希望能夠傳入命名參數,所以我不需要傳入 undefined。
constructor(year?: number,
month?: number,
date?: number)
我希望像這樣創建一個類的實例
const recurrenceRule = new MyNewClass(month: 6)
但它沒有用,我試過了
const recurrenceRule = new MyNewClass(month = 6)
那沒有用。
我讓它工作的唯一方法是
const recurrenceRule = new MyNewClass(undefined, 4)
要么
const recurrenceRule = new MyNewClass(, 4)
但它看起來很混亂,我希望傳入命名參數,因為它們都是可選的,我應該能夠傳入 1 - 對嗎?
您可以使用 ES6 中引入的對象解構來歸檔所需的行為: 引用。 TypeScript 能夠將此功能轉譯為與 ES5 一起使用,以針對較舊的瀏覽器。 然而,從 ES6 開始,這也是完全有效的 JavaScript。
基本上,它看起來像這樣: constructor({ year, month, day})
並被調用,例如,作為new Bar({ year: 2017 })
。 然后你可以在構造函數中訪問year
作為變量,例如分配this.year = year
。
比這更有趣的是使用默認值,例如
constructor({ year = new Date().getFullYear(),
month = new Date().getMonth(),
day = new Date().getDay()
} = {})
它允許分別使用 0、1、2 或 3 個參數調用構造函數(參見下面的代碼片段)。
有點神秘的= {}
用於創建沒有任何參數的新實例的情況。 首先, {}
用作參數對象的默認值。 然后,由於缺少year
,因此添加默認值,然后分別添加月和日。
為了與 TypeScript 一起使用,您當然可以添加其他類型,
constructor({ year = new Date().getFullYear(),
month = new Date().getMonth(),
day = new Date().getDay()
}: { year?: number, month?: number, day?: number } = {}) {
...
}
雖然這看起來真的很神秘。
class Bar { constructor({ year, month, day }) { this.year = year; this.month = month; this.day = day; } log () { console.log(`year: ${this.year}, month: ${this.month}, day: ${this.day}`); } } new Bar({ day: 2017 }).log(); class Foo { constructor({ year = new Date().getFullYear(), month = new Date().getMonth(), day = new Date().getDay() } = {}) { this.year = year; this.month = month; this.day = day; } log () { console.log(`year: ${this.year}, month: ${this.month}, day: ${this.day}`); } } console.log('with default value:'); new Foo().log(); new Foo({ day: 2 }).log(); new Foo({ day: 2, month: 8 }).log(); new Foo({ year: 2015 }).log();
class Bar {
constructor({a, b}: {a?: number, b?: number}) {}
}
new Bar({b: 1})
有關更多信息,請參閱ES6 Object Destructuring with functions 。
簡單參數:
constructor (private recurrenceSettings: {year?: number, month?: number, date?: number})
private 關鍵字將參數實例化為實例變量,省去了在構造函數中實例化的需要。 如果您想實例化公共屬性,也可以是public
。
像這樣使用:
const recurrenceRule = new MyClass({month: 12})
或者使用解構(用法同上):
constructor({day, month, year}: {day?: number, month?: number, year?: number})
盡管上面的版本失去了對實例變量使用私有/公共快捷方式的能力(請參閱https://github.com/Microsoft/TypeScript/issues/5326 )。
您也可以使用Partial來實現相同的結果。
您將以與之前答案相同的方式實例化。
class Bar {
year = new Date().getFullYear();
month = new Date().getMonth();
day = new Date().getDay();
constructor(bar?: Partial<Bar>) {
Object.assign(this, bar);
}
log () {
console.log(`year: ${this.year}, month: ${this.month}, day: ${this.day}`);
}
}
new Bar().log();
new Bar({ day: 2 }).log();
new Bar({ day: 2, month: 8 }).log();
new Bar({ year: 2015 }).log();
注意 1. Partial<Bar>
可以接受任何東西,只要同名的屬性具有相同的類型。 是的,這在某種程度上違反了類型安全。 這仍然強大的原因是,如果您開始使用{
鍵入對象文字,智能感知會告訴您可以初始化哪些屬性。
注意 2. Object.assign
將忽略readonly
屬性,因為它是 JavaScript 特定的東西,而不是 TypeScript 特定的。 這意味着雖然您不能為readonly
屬性分配一個新值,但您當然可以使用Object.assign
。
在某些情況下,擁有一個界面和單獨的 maker 功能會更容易。 (對於未來的讀者。)
interface Foo {
x: number
y: number
}
function newFoo({x=5,y=10}) : Foo {return {x,y}}
const f = newFoo({x:100})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.