route
?route
у тебя - это текущий роут vue-рутера, тогда ошибка у тебя скорее всего выглядит как-то так:TS7053: Element implicitly has an 'any' type because expression of type 'RouteRecordName' can't be used to index type '{ first: string; second: string; }'. No index signature with a parameter of type 'string' was found on type '{ first: string; second: string; }'.
pages
есть ключи типа 'first' | 'second' | ...
, но нет index signature типа string
, т.е. не указано, что ключом может быть любая строка, а не только конкретные'first' | 'second' | ...
. route.name
же после проверки на пустоту имеет тип string | symbol
. Ты не можешь у объекта с чётко ограниченным набором ключей брать значение по произвольному строковому/символьному.pages
позволяющий рандомные ключи, например const pages: Record<PropertyKey, string> = {
first: 'Первая',
second: 'Вторая',
...
}
... = pages[route.name as keyof typeof pages]
name
в route
всегда будет одним из ключей pages
. Уверены же?..export enum ERoutes {
FIRST = 'first',
SECOND = 'second'
}
const routes = [
{
name: ERoutes.FIRST,
...
},
{
name: ERoutes.SECOND,
...
},
...
]
const pages: Record<ERoutes, string> = {
[ERoutes.FIRST]: 'Первая',
[ERoutes.SECOND]: 'Вторая',
...
}
... = pages[route.name as ERoutes]
const routes = [
{
name: 'first',
...
},
{
name: 'second',
...
},
...
] as const satisfies ReadonlyArray<ReadonlyRouteRecordRaw>;
type ReadonlyRouteRecordRaw = Omit<RouteRecordRaw, 'children'> & {
children?: ReadonlyArray<ReadonlyRouteRecordRaw>;
};
type ExtractNames<Route> = Route extends { name: infer Name } ? Name : never;
type FlattenChildren<Route> = Route extends { children: ReadonlyArray<infer Children> }
? FlattenChildren<Children> | Route
: Route;
// с помощью магии ts вытаскиваем в тип RouteNames все заданные у нас имена маршрутов
export type RouteNames = ExtractNames<FlattenChildren<typeof routes[number]>>;
// с помощью магии же прокидывем их прямо в декларацию vue-router
declare module 'vue-router' {
export interface RouteLocationNormalizedLoaded {
name: RouteNames | null | undefined;
}
}
satisfies
- новая фича ts 4.9, в предыдущих версиях того же можно добиться сделав обёртку вида:const narrowRoutesTypeWrapper = <T extends ReadonlyArray<ReadonlyRouteRecordRaw>>(routes: T) => routes;
const routes = narrowRoutesTypeWrapper([ ... ] as const);
const pages: Record<RouteNames, string> = {
first: 'Первая',
second: 'Вторая',
...
}
cities
и airports
(обратите внимание – названия во мн. числе)id | name | другие поля, если нужно
id | city_id | name | другие поля, если нужно
City
и Airport
(обратите внимание – названия в ед. числе)City
создать отношение один-ко-многим (в городе может быть несколько аэропортов)public function airports(): \Illuminate\Database\Eloquent\Relations\HasMany {}
return $this->hasMany(\App\Models\Airport::class);
}
Airport
создать обратное отношениеpublic function city(): \Illuminate\Database\Eloquent\Relations\BelongsTo {}
return $this->belongsTo(\App\Models\City::class);
}
$from = $request->input['otkuda'];
$city = \App\Models\City::whereName($from) // По названию города
->firstOrFail();
// или
// $fromId = $request->input['otkuda'];
// $city = \App\Models\City::findOrFail($fromId); // По ID города
dump($city->toArray()); // Получили город
dump($city->airports->toArray()); // Получили список аэропортов города
$airportId = $request->input['airportId'];
$airport = \App\Models\Airport::findOrFail($airportId);
dump($airport->toArray()); // Получили аэропорт по ID
dump($airport->city->toArray()); // Получили город, в котором этот аэропорт находится.
require-dev
секции + можно дать ссылку на пакет в suggest
секции.if
.function dispatch<T>(key: DispatchKey<T>, value: DispatchValue<T>): void;
function dispatch<T>(keys: DispatchKey<T>[], iterator: (key: DispatchKey<T>) => DispatchValue<T>): void;
function dispatch<T>(
keyOrKeys: DispatchKey<T> | DispatchKey<T>[],
valueOrIterator: DispatchValue<T> | ((key: DispatchKey<T>) => DispatchValue<T>)
): void {
if (Array.isArray(keyOrKeys) && typeof valueOrIterator === 'function') {
setState((prev) => {
const updated = keyOrKeys.map((key) => valueOrIterator(key));
console.log(updated);
return prev;
});
} else {
setState((prev) => ({
...prev,
[keyOrKeys]: valueOrIterator,
}));
}
}
А ещё динамическая типизация сильно экономит время на написание кода - это очень нехилая оптимизация рабочего процесса.
Во-первых, откуда вдруг на клиенте должны появиться огромные объёмы данных, которые будут генерировать эти ошибки и затруднять их поиск? Вы собрались логику на клиенте считать? Тогда у нас уже тут принципиальное несовпадение по вопросам "соответствующих инструментов". Клиент в вебе нужен только для представления. Ну ещё какой-то интерактив - формы, события... Всё.
как мартышка ковыряешься с проставлением типов (а иногда это и не особо очевидно), а потом оказывается что какой-нибудь популярный плагин (условный слайдер) в твоей экосистеме - не типизирован. Ручками писать? Потрошить внутренности плагина? Искать аналог?
declare module 'ldapjs-type-parsers';
, где подставить имя пакета, для которого нет типов.window.addEventListener('load', async () => {
var data1 = await $.getJSON('https://json файл разные');
console.log('Получены данные:', data1);
$(".mypanel").html(data1.hls);
var A = ',{"get":"';
var B = '",';
var C = '"img":"';
var D = '"}';
var master = [A,data1.hls,B,C,D];
var data2 = await $.post('zapros2.php', {name1: master});
console.log('Получены еще данные:', data2);
});
const props = defineProps({
showBgBlue: {
type: Boolean,
default: true,
},
});
const mainClass = computed(() => props.showBgBlue ? 'bg-blueGray-50 py-12' : 'bg-white');
const MyForm = () => {
const name = useSelector((state) => state.user.form.name);
const surname = useSelector((state) => state.user.form.surname);
const email = useSelector((state) => state.user.form.email);
const agree = useSelector((state) => state.user.form.agree);
...
}
const Field = ({ name, ... }) => {
const value = useSelector(...);
...
}
const MyForm = () => {
return (
<FormContainer ...>
<Field name="name"/>
<Field name="surname"/>
<Field name="email"/>
...
</Form>
)
}
class Something {
constructor(private text: string){
}
public static async create(): Promise<Something>{
const text = await Promise.resolve("txt");
return new Something(text);
}
}
let
— const
)