reactjs - 在 React 和 Typescript 中为传单搜索插件分配类型
问题描述
我有以下问题:在我的项目中,我安装了传单库来显示带有图像(建筑物的平面图)的地图,并且每张地图都有一个Point,它是一个GeoJson Point,它象征着该特定楼层内的扇区。
由于每一层都有很多点,所以我搜索了传单插件,其中一个满足了我的期望,传单搜索。但碰巧 TypeScript 无法识别它的类型,特别是在 L.Control.Search() 中,声称 Control 没有 typeof 'Search'。
尝试安装一些
npm i --save-dev @types/leaflet-search
但在 npm 存储库中找不到它。有趣的是,运行npm run dev
它可以完美运行,按照我需要的方式搜索点,如下图所示:
但是在使用时npm run build
,它会给出这种类型的“搜索”错误。我将向您展示代码:
组件/Leaflet.tsx
import L, { LatLngBounds } from 'leaflet';
import 'leaflet/dist/leaflet.css';
import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.webpack.css';
import 'leaflet-defaulticon-compatibility';
//https://www.npmjs.com/package/leaflet-fullscreen
import 'leaflet-fullscreen';
import 'leaflet-fullscreen/dist/leaflet.fullscreen.css';
//https://www.npmjs.com/package/leaflet-search
import 'leaflet-search/src/leaflet-search.js';
import 'leaflet-search/src/leaflet-search.css';
import { useCallback, useEffect, useRef } from 'react';
import { LeafletProps } from './type';
const style = { border: '1px black solid', width: '100%', height: '500px' };
export default function Leaflet({
id,
cover,
sector,
floorBuild,
buildName,
}: LeafletProps) {
const mapContainerRef = useRef(null);
const container = document.getElementById(`${id}`);
if (container) {
container.remove();
}
//Função de inicio do component
const loadInitial = useCallback(
(map, cover, geoJson, floorBuild, buildName) => {
let internalFloor = '';
switch (floorBuild) {
case 0:
internalFloor = 'Térreo';
break;
case 1:
internalFloor = '1ª andar';
break;
case 2:
internalFloor = '2ª andar';
break;
case 3:
internalFloor = '3ª andar';
break;
case 4:
internalFloor = '4ª andar';
break;
default:
internalFloor = '';
}
const bounds = new LatLngBounds([0, 0], [cover.height, cover.width]);
L.imageOverlay(`${cover.srcImg}`, bounds).addTo(map);
map.fitBounds(bounds);
map.setView([cover.height / 2, cover.width / 2], -2);
const featuresLayer = L.geoJSON(geoJson, {
onEachFeature: (feature, layer) => {
let popupContent = ``;
if (feature.properties && feature.properties.name) {
popupContent += `<p>${feature.properties.name}</p>`;
}
layer.bindPopup(popupContent);
},
attribution: `© ${buildName} - ${internalFloor}`,
});
map.addLayer(featuresLayer);
//Apenas para coletar os dados
function onMapClick(e) {
console.log(e.latlng.toString());
}
map.on('click', onMapClick);
//Search
// eslint-disable-next-line no-use-before-define
const searchControl = new L.Control.Search({
layer: featuresLayer,
propertyName: 'name',
marker: false,
autoType: false,
});
searchControl
.on('search:locationfound', function (e) {
if (e.layer._popup) e.layer.openPopup();
})
.on('search:collapsed', function (e) {
featuresLayer.eachLayer(function (layer) {
//restore feature color
featuresLayer.resetStyle(layer);
});
});
map.addControl(searchControl);
},
[],
);
useEffect(() => {
const map = L.map(mapContainerRef.current, {
crs: L.CRS.Simple,
zoom: 5,
minZoom: -3,
maxZoom: 5,
fullscreenControl: true,
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const geoJson: GeoJSON.FeatureCollection<any> = {
type: 'FeatureCollection',
features: [],
};
floorBuild++;
sector.map((s) => {
if (s.mapLat != null && s.mapLon != null) {
if (floorBuild === s.floor.floorNumber) {
const item: GeoJSON.Feature = {
type: 'Feature',
properties: {
name: `${s.name} - ${s.initials}`,
},
geometry: {
type: 'Point',
coordinates: [s.mapLat, s.mapLon],
},
};
geoJson.features.push(item);
}
}
});
loadInitial(map, cover, geoJson, floorBuild, buildName);
// unmount map function
return () => {
map.off();
map.remove();
};
}, [loadInitial, sector, cover, floorBuild, buildName]);
return (
<>
<div
id={id}
className="maps-Builds"
ref={mapContainerRef}
style={style}
></div>
<br />
</>
);
}
包.json
{
"name": "faqs-bancada",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"debug": "NODE_OPTIONS='--inspect' next dev",
"build": "next build",
"export": "next export",
"start": "next start",
"storybook": "start-storybook -p 6006 -s ./public",
"build-storybook": "build-storybook",
"test": "jest",
"deploy-static": "npm run build && npm run export",
"lint": "eslint src --max-warnings=0",
"lint-staged": "lint-staged",
"prepare": "husky install"
},
"dependencies": {
"@styled-icons/boxicons-logos": "^10.37.0",
"@styled-icons/boxicons-regular": "^10.37.0",
"@styled-icons/evaicons-outline": "^10.34.0",
"@styled-icons/material-outlined": "^10.28.0",
"anchor-js": "^4.3.1",
"bootstrap": "^4.6.0",
"d3-mitch-tree": "^1.1.2",
"graphql": "^15.6.1",
"graphql-request": "^3.5.0",
"leaflet": "^1.7.1",
"leaflet-defaulticon-compatibility": "^0.1.1",
"leaflet-fullscreen": "^1.0.2",
"leaflet-search": "^3.0.2",
"next": "^11.1.0",
"prop-types": "^15.7.2",
"react": "17.0.1",
"react-bootstrap": "^1.6.4",
"react-data-table-component": "^7.4.4",
"react-data-table-component-extensions": "^1.5.2",
"react-data-table-component-with-filter": "^7.0.1",
"react-dom": "17.0.1",
"react-leaflet": "^3.2.2",
"styled-components": "^5.2.1"
},
"devDependencies": {
"@babel/core": "^7.15.8",
"@storybook/addon-actions": "^6.3.11",
"@storybook/addon-docs": "^6.3.11",
"@storybook/addon-essentials": "^6.3.11",
"@storybook/addon-links": "^6.3.11",
"@storybook/react": "^6.3.11",
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.3.0",
"@types/anchor-js": "^4.2.1",
"@types/express": "^4.17.13",
"@types/leaflet": "^1.7.5",
"@types/leaflet-fullscreen": "^1.0.5",
"@types/node": "^14.17.22",
"@types/react": "^17.0.29",
"@types/styled-components": "^5.1.15",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"babel-loader": "^8.2.2",
"babel-plugin-styled-components": "^1.12.0",
"eslint": "^7.22.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-react": "^7.26.1",
"eslint-plugin-react-hooks": "^4.2.0",
"husky": "^5.1.3",
"jest": "^26.6.3",
"jest-styled-components": "^7.0.3",
"lint-staged": "^10.5.4",
"msw": "^0.35.0",
"node-fetch": "^3.0.0",
"prettier": "^2.2.1",
"storybook-addon-next-router": "^3.0.8",
"typescript": "^4.4.4"
},
"lint-staged": {
"src/**/*": [
"npm run lint -- --fix"
]
}
}
构建时出现此错误:
PS D:\JSProjects\faqs-bancada> npm run deploy-static
> faqs-bancada@0.1.0 deploy-static D:\JSProjects\faqs-bancada
> npm run build && npm run export
> faqs-bancada@0.1.0 build D:\JSProjects\faqs-bancada
> next build
info - Using webpack 5. Reason: Enabled by default https://nextjs.org/docs/messages/webpack5
Failed to compile.
./src/components/Leaflet/index.tsx:92:43
Type error: Property 'Search' does not exist on type 'typeof Control'.
90 | //Search
91 | // eslint-disable-next-line no-use-before-define
> 92 | const searchControl = new L.Control.Search({
| ^
93 | layer: featuresLayer,
94 | propertyName: 'name',
95 | marker: false,
info - Checking validity of types .npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! faqs-bancada@0.1.0 build: `next build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the faqs-bancada@0.1.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\paulo\AppData\Roaming\npm-cache\_logs\2021-10-16T13_38_12_506Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! faqs-bancada@0.1.0 deploy-static: `npm run build && npm run export`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the faqs-bancada@0.1.0 deploy-static script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\paulo\AppData\Roaming\npm-cache\_logs\2021-10-16T13_38_12_544Z-debug.log
错误始终是:类型错误:“typeof Control”类型上不存在属性“搜索”
我尝试寻找一些 eslint 评论,例如eslint-disable-next-line no-use-before-define,但效果不佳。
我的问题是:如何为 Search 分配一个类型,以便我可以正常构建项目?如何解决此错误?
解决方案
推荐阅读
- sql - 如何使用一个查询提取当前日期和下一个日期
- java - 是否可以通过 Java 中的 Telegram API 发送邮件(不是机器人)
- vb.net - 尝试使用 Blue Prism 对 HTTP 请求令牌进行 API 时出现错误“字典中不存在给定的密钥”
- python - 如何在期望脚本中读取发送命令输出
- loops - 我如何优化ansible的剧本
- prestashop - 如何在 smarty 中将点转换为逗号
- php - 当您在本地开发 Magento 时,请求需要多长时间?
- c++ - 在 CurrentProject 中使用 ExternalProject 的目标
- android - 如何根据设备方向动态更改 LinearLayout 方向
- pdf - 是否有任何解决方案可以自动修复 PDF 以符合可访问性要求?