const queryKey: AuthMessagesKeys = queryObject.message
function isAuthMessagesKey(str: string): str is AuthMessagesKeys {
return ['login', 'logout', 'session'].includes(str);
}
const loader_1 = new GCodeLoader();
const loader_2 = new AMFLoader();
let ask_1 = true;
let ask_2 = true;
async function main() {
console.log('Start load')
if (ask_1){
const amfobject = await loader_1.loadAsync( './models/amf/rook.amf');
scene.add( amfobject );
console.log('on loader AMF', amfobject);
}
if (ask_2){
const object = await loader_2.loadAsync( 'models/gcode/benchy.gcode');
scene.add( object );
console.log('on loader GCode', object);
}
console.log('END load')
}
main();
Promise
- это просто хитрая надстройка надо коллбэками(полностью реализуемая на обычном js), позволяющая развернуть их порядок назначения - не более. async-await
- просто синтаксический сахар над Promise
, делающий оные менее многословными, но не меняющий механизма. PropsWithChildren<Props>
. Но под капотом он просто делает так: type PropsWithChildren<P> = P & { children?: ReactNode };
type TwitterProps = {
children: (user: string) => ReactNode
}
const response: ITwitter = ...
. Только если какая-нить хрень прилетит то может сломаться в рантайме, так что либо ты доверяешь серверу, либо используешь какую-нить либу для дополнительной проверки вживую.) type WritableFields<T> = Partial<Pick<T, WritableKeys<T>>>;
export function createElement<K extends keyof HTMLElementTagNameMap>(tag: K, options?: WritableFields<HTMLElementTagNameMap[K]>): HTMLElementTagNameMap[K] {
let element = document.createElement(tag)
if (options) {
// assign options
Object.assign(element, options);
}
return element
}
type WritableFields<T> = Partial<Pick<T, WritableKeys<T>>>;
export function createElement<K extends keyof HTMLElementTagNameMap>(tag: K, options?: WritableFields<HTMLElementTagNameMap[K]>): HTMLElementTagNameMap[K] {
let element = document.createElement(tag)
if (options) {
// assign options
let option: keyof typeof options;
for (option in options) {
element[option] = options[option]!; // ! - потому что теоретически ты можешь передать undefined явно, но морочиться с этим не стоит
}
}
return element
}
interface Foo {
foo: number;
}
тебе ничего не мешает передать ему {
foo: 1,
bar: 2
}
, т.к. данный объект расширяет интерфейс Foo и, соответственно, удовлетворяет ему. Получается, что внутри функции typescript никак не может быть уверен, что ключи указанные в интерфейсе - это ВСЕ ключи, а значит не может быть уверен, что при переборе и присвоении не будет присвоено что-то лишнее. (Это не говоря уже о прототипах, геттерах и прочем) Vue
появились дополнительные свойства типа $route
. Надо отдельно подключать декларации вручную, либо следовать инструкции выше. getMediaUrls
пока не будет данных. getMediaUrls
должно быть computed
свойство mediaUrls
; во-вторых: скрывайте в шаблоне отображение пока не появятся данные: v-if="currentProductData"
/v-if="currentProductData.length"
и показывайте вместо этого какой-нить loader, Vue не запросит то, что скрыто под v-if
пока условие не станет верным.getMediaUrls
в mounted
и разрывать асинхронную цепочку. Вызывайте его сразу в getProductData
, либо если currentProductData
может меняться в иных случаях - сделайте, опять же, computed свойством. В крайнем случае можно вызывать его, повесив watch
на currentProductData
, но computed
лучше.