我正在將 Typescript 與 Playwright 一起使用,但我不確定 Page 物件模型的最佳實踐是什么。
例如:
export class OrderConfirmationPage extends GenericPage {
readonly orderConfirmationMessage: Locator;
constructor(page: Page) {
super(page);
this.orderConfirmationMessage = page.locator(
'.checkout-success__body__headline'
);
}
public getOrderConfirmationMessage(): Locator {
return this.orderConfirmationMessage;
}
}
如果我直接訪問該欄位,這個 getter 方法是必要的還是相同的?
直接地:
orderConfirmationPage.orderConfirmationMessage
使用吸氣劑:
orderConfirmationPage.getOrderConfirmationMessage()
uj5u.com熱心網友回復:
差異與“只讀”的實施地點、時間和程度有關。
TypeScript 中的readonly
屬性是純粹的編譯時構造;該readonly
部分與靜態型別系統的其余部分一起從發出的 JavaScript 中洗掉。因此,雖然您會在編譯時收到有關寫入readonly
屬性的警告,但沒有什么能阻止它在運行時發生:
class Foo { readonly a: number = 1; }
const foo = new Foo();
foo.a = 2; // compiler error, but no runtime error
// Cannot assign to 'a' because it is a read-only property.
console.log(foo.a) // 2, not 1
當然,幾乎所有 TypeScript 的靜態型別系統都可以這樣說。沒有什么能“阻止”你這樣做:
const thisToo: string = 1; // compiler error
但我們通常假設 TypeScript 開發人員會在這些錯誤進入運行時之前修復這些錯誤,或者任何違反 TypeScript 型別的運行時違規都超出了范圍。
可以說更糟糕的是readonly
屬性只影響直接寫入而不影響型別兼容性的事實。所以下面的代碼是完全合法的 TypeScript:
interface Bar {a: number}
const bar: Bar = foo; // okay
bar.a = 3; // okay
console.log(foo.a) // 3
microsoft/TypeScript#13347有一個長期開放的請求,以防止readonly
可變屬性之間的兼容性,但目前它不是語言的一部分。
另一方面,您不能分配給方法的回傳值,這是一個語法錯誤嘗試:
class Foo {
readonly a: number = 1;
getA() { return this.a }
}
// foo.getA() = 4; // compiler error and runtime error
所以一個方法肯定會使其輸出有效地只讀,即使在運行時也是如此。當然,同時擁有一個readonly
屬性和一個方法就達不到目的了。該方法就像一扇鎖著的門,但readonly
它參考的屬性就像一扇敞開的門,上面寫著“不要使用這扇門”。這是否可以接受取決于您需要多么嚴重地保護門后的任何東西。
如果你真的想從外部強制閱讀,你可以做幾件事。一種是您可以使用該Object.defineProperty()
方法使該屬性writable
在運行時變為 non- :
class Foo {
readonly a!: number;
constructor() {
Object.defineProperty(this, "a", { value: 1 })
}
}
const foo = new Foo();
try {
foo.a = 2; // compiler error,
} catch (e) {
console.log(e); // "a" is read-only
}
或者您可以使用私有屬性和實際的getter 訪問器,這在概念上與您所做的類似:
class Foo {
#a: number = 1;
get a() {
return this.#a
}
}
const foo = new Foo();
try {
foo.a = 2; // compiler error,
} catch (e) {
console.log(e); // setting getter-only property "a"
}
注意:這些都與屬性本身是否是可變物件無關。像 a 這樣的原語number
不能被修改,但物件可以,而且無論readonly
是私有的還是 getter 都不會對此做任何事情:
class Baz {
#p: { a: number } = { a: 1 }
getP() { return this.#p };
}
const baz = new Baz();
// baz.#p = {a: 5} // invalid at runtime
// baz.getP() = {a: 5} // invalid at runtime
baz.getP().a = 5; // no error at compile time or runtime
console.log(baz.getP().a) // 5
有一些方法可以避免這種情況,但對其進行討論會偏離所問問題的主題。
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/522080.html
標籤:打字稿编剧测试