我有一个Vue 3/Vite/TS应用程序,在npm run dev
中运行时运行良好,但由于错误TS2345
而无法构建。我知道这是一个与打字有关的错误,但我无法理解错误到底在哪里。
transforming (15) node_modules\@vue\reactivity\dist\reactivity.esm-bundler.src/TimesView.vue:15:18 - error TS2345: Argument of type '{ key: () => number; id: string; class: string; }' is not assignable to parameter of type 'HTMLAttributes & ReservedProps & Record<string, unknown>'.
Type '{ key: () => number; id: string; class: string; }' is not assignable to type 'ReservedProps'.
Types of property 'key' are incompatible.
Type '() => number' is not assignable to type 'string | number | symbol | undefined'.
15
<div
v-for="hourAtDefaultCity in [...Array(24).keys()].map(x => locTime(x, city.timezone))"
:key="hourAtDefaultCity.toUnixInteger"
id="hour"
class="flex justify-center place-content-between text-xl grow"
:class="{ 'bg-gray-300 text-gray-400': isNightLocallyForHourAtDefaultCity(hourAtDefaultCity.hour, city.timezone), 'bg-sky-100 text-sky-900': !isNightLocallyForHourAtDefaultCity(hourAtDefaultCity.hour, city.timezone) }"
>
从堆栈底部开始,我了解到错误实际上是关于() => number
(因此,函数的返回值应该是number
)的,该错误不能分配给一组类型的字符串|number|符号|未定义'。这是我不明白的:number
就是其中之一。isNightLocallyForHourAtDefaultCity
的声明如下:
const locTime = (hour: number, timezone: string): DateTime => DateTime.fromISO(`${hour.toString().padStart(2, '0')}:00`, { zone: defaultTimezone.value }).setZone(timezone)
const isNightLocallyForHourAtDefaultCity = (hour: number, timezone: string): boolean => locTime(hour, timezone).hour < config.value.dayStartHour || locTime(hour, timezone).hour > config.value.dayEndHour
我在哪里会有() => number
TS抱怨?
编辑:为了安全起见,下面是组件的完整代码(包括TS不抱怨的部分,当然还有我上面提到的所有内容)
<template>
<div class="flex justify-center h-screen">
<div class="flex flex-row" id="cities">
<div v-for="city in config.cities" :key="city.name" class="flex flex-col shrink-0 justify-between">
<div class="cityName items-center mb-3 flex flex-col" :class="{ 'bg-green-200': city.name === config.defaultCity }">
<div class="text-center font-extrabold text-4xl" :style="maxCityNameSizeStyle" ref="maxCityNameSizeRefs">
{{ city.name }}
</div>
<div class="">
{{ now.setZone(city.timezone).toFormat('HH:mm') }}
</div>
</div>
<!-- iterate over the column of hours of the default city, adapting the dispayed to the city tz -->
<div v-for="hourAtDefaultCity in [...Array(24).keys()].map(x => locTime(x, city.timezone))" :key="hourAtDefaultCity.toUnixInteger" id="hour" class="flex justify-center place-content-between text-xl grow" :class="{ 'bg-gray-300 text-gray-400': isNightLocallyForHourAtDefaultCity(hourAtDefaultCity.hour, city.timezone), 'bg-sky-100 text-sky-900': !isNightLocallyForHourAtDefaultCity(hourAtDefaultCity.hour, city.timezone) }">
<span>⸺</span>
<span class="font-bold">{{ hourAtDefaultCity.toFormat('HH') }}</span>
<span>:</span>
<span>{{ hourAtDefaultCity.toFormat('mm') }}</span>
<span>⸺</span>
</div>
</div>
</div>
<time-bar :now="now" :config="config" :maxCityNameSize="maxCityNameSize" :defaultTimezone="defaultTimezone"></time-bar>
</div>
</template>
<script setup lang="ts">
import { DateTime } from "luxon";
import { onMounted, ref, watch } from 'vue'
import TimeBar from './TimeBar.vue'
import { config } from "./config";
const props = defineProps({
defaultTimezone: {
type: String,
default: 'Etc/UTC'
}
})
const defaultTimezone = ref(props.defaultTimezone)
// global current time, updated every X seconds
const now = ref(DateTime.now())
// setInterval(() => (now.value = DateTime.now()), 1000)
// compute the time to display based on the hour number of the other ones
const locTime = (hour: number, timezone: string): DateTime => DateTime.fromISO(`${hour.toString().padStart(2, '0')}:00`, { zone: defaultTimezone.value }).setZone(timezone)
const isNightLocallyForHourAtDefaultCity = (hour: number, timezone: string): boolean => locTime(hour, timezone).hour < config.value.dayStartHour || locTime(hour, timezone).hour > config.value.dayEndHour
const maxCityNameSize = ref(0)
const maxCityNameSizeStyle = ref('')
watch(() => config.value, () => console.log(`config in times view changed: ${JSON.stringify(config.value)}`))
onMounted(() => {
// style for the width of the column
maxCityNameSize.value = Math.max(...Array.from(document.querySelectorAll('.cityName')).map((x) => x.clientWidth))
maxCityNameSizeStyle.value = `width: ${maxCityNameSize.value}px`
// location.href = 'http://localhost:5173/?cities=San_Diego,America/Los_Angeles;Paris,Europe/Paris;Boston,America/New_York;Pune,Asia/Kolkata;Tokyo,Asia/Tokyo;UTC,Etc/UTC&default=UTC'
})
</script>
1条答案
按热度按时间irtuqstp1#
你正在传入一个函数
key
,Typescript告诉你
key
必须是string | number | symbol | undefined
。我认为你想执行函数而不是传递它: