[英]Is this a good conversion to typescript? Why this error?
我有這段代碼可以在需要時調整 textarea 元素的大小:
function resize({ target }) {
target.style.height = '1px'
target.style.height = +target.scrollHeight + 'px'
}
export function textareaResize(el) {
resize({ target: el })
el.style.overflow = 'hidden'
el.addEventListener('input', resize)
return {
destroy: () => el.removeEventListener('input', resize)
}
}
我正在嘗試將此代碼轉換為 Typescript 為:
function resize(event: Event) {
const target = event.target as HTMLTextAreaElement
target.style.height = '1px'
target.style.height = `${+target.scrollHeight}px`
}
export function textareaResize(el: HTMLTextAreaElement): { destroy: () => void} {
resize({ target: el })
el.style.overflow = 'hidden'
el.addEventListener('input', resize)
return {
destroy: () => el.removeEventListener('input', resize)
}
}
但是我在resize({ target: el })
行顯然有這個錯誤:
Argument of type '{ target: HTMLTextAreaElement; }' is not assignable to parameter of type 'Event'.
Type '{ target: HTMLTextAreaElement; }' is missing the following properties from type 'Event': bubbles, cancelBubble, cancelable, composed, and 17 more.ts(2345)
我該如何解決?
也許我用錯了把它改成這樣: function resizeTextArea(event: Event)
,對吧?
第一個問題是:當resizeTextArea
只使用其中的target
時,為什么需要一個Event
? 我天真的第一次重構是:
function resizeTextArea(target: HTMLTextAreaElement) {
target.style.height = '1px'
target.style.height = `${+target.scrollHeight}px`
}
export function textareaResize(element: HTMLTextAreaElement): { destroy: () => void} {
resizeTextArea(element)
element.style.overflow = 'hidden'
element.addEventListener('input', (e: Event) => resizeTextArea(e.target as HTMLTextAreaElement))
return {
destroy: () => element.removeEventListener('input', (e: Event) => resizeTextArea(e.target as HTMLTextAreaElement))
}
}
如果您出於某種原因想堅持使用Event
,可以將{target}
轉換為Event
:
function resizeTextArea(event: Event) {
const target = event.target;
target.style.height = '1px'
target.style.height = `${+target.scrollHeight}px`
}
export function textareaResize({ target }: HTMLTextAreaElement): { destroy: () => void} {
resizeTextArea({ target } as Event)
element.style.overflow = 'hidden'
element.addEventListener('input', resizeTextArea)
return {
destroy: () => element.removeEventListener('input', (e: Event) => resizeTextArea)
}
}
請注意,這不是最安全的方法,因為您實際上是在textareaResize
中構造一個不完整的Event
,這會在resizeTextArea
中創建一個隱含且難以理解的合同:在該 function 工作的人需要知道該event
是,在事實上,不是一個完整的Event
,而只是一個具有target
屬性的 object 。
普通的 object 不是事件:
resizeTextArea({ target: element })
沒有將 Event 傳遞給resizeTextArea
,因此 TS 失敗。
一種選擇是改用this
,輸入HTMLTextAreaElement
:
function resizeTextArea(this: HTMLTextAreaElement) {
this.style.height = '1px'
this.style.height = `${+this.scrollHeight}px`
}
export function textareaResize(element: HTMLTextAreaElement): { destroy: () => void} {
resizeTextArea.call(element)
element.style.overflow = 'hidden'
element.addEventListener('input', resizeTextArea)
return {
destroy: () => element.removeEventListener('input', resizeTextArea)
}
}
(如果你也需要事件參數,你可以做function resizeTextArea(this: HTMLTextAreaElement, event?: Event) {
)
您正在嘗試將 HTMLTextAreaElement 類型的目標傳遞給具有 Event 類型參數的 function。 嘗試這個:
function resize(target: HTMLTextAreaElement) {
target.style.height = '1px'
target.style.height = `${+target.scrollHeight}px`
}
export function textareaResize(el: HTMLTextAreaElement): { destroy: () => void} {
resize({ target: el })
el.style.overflow = 'hidden'
el.addEventListener('input', resize)
return {
destroy: () => el.removeEventListener('input', (event: Event) => resize( event.target as HTMLTextAreaElement ))
}
}
類型系統是用來保護你的……不要試圖“投射”你的方式只是為了讓代碼編譯。 錯誤消息告訴您,此 object 不支持超過 20 項預期的“事件”。 而且,很明顯,“HTML 文本區域元素”不是“事件”,也永遠不會是。 不幸的是,你一開始沒有告訴我們你為什么要這么做。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.