Я работаю над проектом Typescript Vue с Leaflet. Я нашел код для ленивой загрузки маркеров карты, но он был написан на Javascript. Он работает нормально, но я получаю ошибки VSCode и предупреждения компилятора, потому что this не набирается. Как набрать this?
Обновление 1: я получил первый тип для разрешения, используя предложение @aplet123 ниже. Но я не могу понять второй на this._updateIconVisibility. Я думаю, это потому, что я на самом деле использую функцию для расширения существующей функциональности (т.е. _updateIconVisibility на самом деле не существует в типе). Итак, что мне теперь делать? Я подозреваю, что лучше всего просто создать собственный класс с нужными мне методами, но я не знаю, действительно ли на самом деле более распространено предоставлять, возможно, анонимный объект или что-то еще...
L.Marker.addInitHook(function (this: L.Marker) {
this.on(
'add',
function () {
this._updateIconVisibility = function () {
var map = this._map,
isVisible = map.getBounds().contains(this.getLatLng()),
wasVisible = this._wasVisible,
icon = this._icon,
iconParent = this._iconParent,
shadow = this._shadow,
shadowParent = this._shadowParent
// remember parent of icon
if (!iconParent) {
iconParent = this._iconParent = icon.parentNode
}
if (shadow && !shadowParent) {
shadowParent = this._shadowParent = shadow.parentNode
}
// add/remove from DOM on change
if (isVisible != wasVisible) {
if (isVisible) {
iconParent.appendChild(icon)
if (shadow) {
shadowParent.appendChild(shadow)
}
} else {
iconParent.removeChild(icon)
if (shadow) {
shadowParent.removeChild(shadow)
}
}
this._wasVisible = isVisible
}
}
// on map size change, remove/add icon from/to DOM
this._map.on(
'resize moveend zoomend',
this._updateIconVisibility,
this
)
this._updateIconVisibility()
},
this
)
})
это связано с конфигурацией вашего проекта vuejs.org/v2/guide/typescript.html обновите tsconfig.json и установите strict: true
@ Aplet123 Спасибо, это работает в первом случае. Я обновил свой вопрос. Кроме того, если позже я столкнусь с ситуацией, когда у функции есть обязательные аргументы, будет ли это работать? Могу ли я просто передать эти аргументы после аргумента this, и они будут в правильном порядке?
@BooklynDadCore Спасибо, я уже установил strict: true в своем .tsconfig






Я не очень хорошо знаком с вашей средой (Vue и т. д.), но мне удалось создать следующий файл, который устраняет ошибки и, надеюсь, демонстрирует путь вперед. Вероятно, его можно было бы улучшить, если бы я знал больше.
Ключ действительно описывает ваши this типы на каждом этапе. Поэтому я создал небольшую структуру, создал тип MyObject для описания декораций, которые вы реализуете, а затем объявил this типом MyObject в соответствующем месте.
См. ниже и дайте мне знать, если есть что-то непонятное.
// Scaffolding to account for things from the environment
namespace L {
type handler = () => void
type target = object;
export type on = (types: string, handler: handler, target: target) => void
export interface Marker {
on: on
}
}
const L = {
Marker: {
addInitHook: function(f: (this: L.Marker) => void) {
// just here because your code must be supplying it
}
}
}
// A type to add to your code
namespace L {
export type MyObject = {
_updateIconVisibility: () => void,
_map: {
on: on
}
}
}
// Your code above, now with no objection from the TypeScript compiler
L.Marker.addInitHook(function (this: L.Marker) {
this.on(
'add',
function (this: L.MyObject) {
this._updateIconVisibility = function () {
var map = this._map,
isVisible = map.getBounds().contains(this.getLatLng()),
wasVisible = this._wasVisible,
icon = this._icon,
iconParent = this._iconParent,
shadow = this._shadow,
shadowParent = this._shadowParent
// remember parent of icon
if (!iconParent) {
iconParent = this._iconParent = icon.parentNode
}
if (shadow && !shadowParent) {
shadowParent = this._shadowParent = shadow.parentNode
}
// add/remove from DOM on change
if (isVisible != wasVisible) {
if (isVisible) {
iconParent.appendChild(icon)
if (shadow) {
shadowParent.appendChild(shadow)
}
} else {
iconParent.removeChild(icon)
if (shadow) {
shadowParent.removeChild(shadow)
}
}
this._wasVisible = isVisible
}
}
// on map size change, remove/add icon from/to DOM
this._map.on(
'resize moveend zoomend',
this._updateIconVisibility,
this
)
this._updateIconVisibility()
},
this
)
})
Ответ Дэвида заставил меня просто определить интерфейс, который содержит элементы для расширенной функциональности. В итоге это выглядит так:
interface LazyMarker extends Marker {
_wasVisible: boolean
_icon: ((Node & ParentNode) | null) & Icon
_iconParent: (Node & ParentNode) | null
_shadowParent: (Node & ParentNode) | null
_updateIconVisibility(): void
}
// this hook makes the markers lazy load
// increases performance of map scrolling/moving
L.Marker.addInitHook(function (this: LazyMarker) {
this.on(
'add',
function (this: LazyMarker) {
this._updateIconVisibility = function (this: LazyMarker) {
var map = this._map,
isVisible = map.getBounds().contains(this.getLatLng()),
wasVisible = this._wasVisible,
icon = this._icon,
iconParent = this._iconParent,
shadow = this._shadow,
shadowParent = this._shadowParent
// remember parent of icon
if (!iconParent) {
iconParent = this._iconParent = icon.parentNode
}
if (shadow && !shadowParent) {
shadowParent = this._shadowParent = shadow.parentNode
}
// add/remove from DOM on change
if (iconParent != null && isVisible != wasVisible) {
if (isVisible) {
iconParent.appendChild(icon)
if (shadowParent != null && shadow) {
shadowParent.appendChild(shadow)
}
} else {
iconParent.removeChild(icon)
if (shadowParent != null && shadow) {
shadowParent.removeChild(shadow)
}
}
this._wasVisible = isVisible
}
}
// on map size change, remove/add icon from/to DOM
this._map.on(
'resize moveend zoomend',
this._updateIconVisibility,
this
)
this._updateIconVisibility()
},
this
)
})
Дайте функции типизированный аргумент с именем
this(это не фактический аргумент, и он не будет скомпилирован в результирующий javascript, он просто обозначает типthis).