#typescript #svelte #typescript-generics
Вопрос:
Я хочу принять компонент в качестве опоры.
import AComponent from './AComponent.svelte';
type MyType = {
[key: string]: any; // just an example
}
type IWantToAcceptAComponent<T> = {
component: SvelteComponentTyped<{ record: T }>;
}
const componentPropObject: IWantToAcceptAComponent<MyType> = {
component: AComponent // error here
}
Error: Type 'typeof AComponent__SvelteComponent_' is missing the following properties from type
'SvelteComponentTyped<{ record: MyType; }>': $set, $on, $destroy, $prop_def, and 5
more.ts(2740)
Я подумал, что, возможно, typedef должен быть:
type IWantToAcceptAComponent<T> = {
component: typeof SvelteComponentTyped<{ record: T }>;
}
Но это приводит к еще более странным ошибкам.
Довольно важно, чтобы этот ввод был явным, так как он должен быть частью экспортируемого интерфейса для пользователей.
Комментарии:
1. насколько я знаю, не очень хорошая идея передавать компонент в качестве реквизита
2. почему вы хотите передать компонент в качестве реквизита
3. Главным образом потому, что компонент чрезвычайно основан на данных, и единственный способ, которым я могу сохранить все связанные типы, ну, связанные,-это управлять этими отношениями с помощью типов реквизитов, которые я передаю. Кроме того, ошибочно говорить, что передавать компонент в качестве реквизита (или, по крайней мере, части объекта) — плохая идея… это буквально в быстром старте! svelte.dev/учебник/стройный компонент
Ответ №1:
Вам нужно настроить свой набор текста IWantToAcceptAComponent
. Вы не можете использовать SvelteComponentTyped
напрямую, потому что это означает, что вам нужен тип экземпляра, а не тип конструктора. Но вы также не можете этого сделать typeof SvelteComponentType<..some generic>
, потому что это синтаксическая ошибка для машинописного текста. Вам нужно ввести «принимает конструктор класса, который возвращает определенный экземпляр» , как это:
type IWantToAcceptAComponent<T> = {
component: new (...args: any) => SvelteComponentTyped<{ record: T }>;
}
Обратите внимание, что вам нужна стройность для VS Code версии 105 или выше и (если вы ее используете) svelte-check
2.0.0 или выше, чтобы это работало. Ранее было небольшое несоответствие между наборами.
Если вы хотите использовать код внутри файла машинописи, вам необходимо активировать плагин машинописи расширения Svelte для VS Code. В противном случае все импортные данные Svelte будут типизированы как универсальные SvelteComponentDev
без соответствующих типов.
Комментарии:
1. Ты спаситель-я думал, что ответил на это раньше! Большое спасибо за помощь. Вот и позаботились об этом!
2. Боже, я заговорил слишком рано-казалось, что это работает, но это не так. Теперь я получаю эту ошибку: тип «typeof SvelteComponentDev» не может быть присвоен типу » new (…args: любой) => SvelteComponentTyped><{ запись: Строка<AmenityRuleRow>; }, любой, любой<AmenityRuleRow>>». Есть какие-нибудь идеи?
3. Я подозреваю, что вы хотите использовать код внутри файла TS. Я соответствующим образом обновил свой ответ. В общем, взаимодействие файлов TS/Svelte сложно и иногда не совсем совпадает, и вам нужен плагин TS, чтобы улучшить взаимодействие.
Ответ №2:
Несмотря на то, что я не использую typescript, я не вижу причин, по которым это было бы возможно с чистым JS, но не с TS. Я сделал REPL, который в основном включает в себя два других «вспомогательных компонента», переданных в качестве реквизита.
Структура представляет собой что-то вроде :
Приложение.стройная
<script>
//App.svelte
import A from "./A.svelte";
import B from "./B.svelte";
import Wrapper from "./Wrapper.svelte";
let props = [ { component: A }, { component: B } ];
</script>
<Wrapper {props} />
Обертка.стройная :
<script>
//Wrapper.svelte
export let props = [];
</script>
{#each props as prop}
<p>
<svelte:component this={prop.component} />
</p>
{/each}
A. стройная :
<!-- A.svelte -->
<h2>COMP A</h2>
B. стройная :
<!-- B.svelte -->
<h3>COMP B</h3>
Комментарии:
1. Вы абсолютно правы-это возможно! Вопрос в том, какие шрифты необходимы, чтобы сделать его строго типизированным. Если я просто изменю определение типа на компонент: любой, все будет хорошо и хорошо. Но я бы предпочел сильный шрифт.