refactor(client): add proper types to `never[]` (#9340)

This commit is contained in:
Kagami Sascha Rosylight 2022-12-18 13:13:05 +09:00 committed by GitHub
parent af9034355c
commit bb3d274db6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 28 deletions

View File

@ -54,13 +54,13 @@ export default defineComponent({
return t.match(/^[0-9.]+s$/) ? t : null; return t.match(/^[0-9.]+s$/) ? t : null;
}; };
const genEl = (ast: mfm.MfmNode[]) => concat(ast.map((token): VNode[] => { const genEl = (ast: mfm.MfmNode[]) => ast.map((token): VNode | string | (VNode | string)[] => {
switch (token.type) { switch (token.type) {
case 'text': { case 'text': {
const text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n'); const text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n');
if (!this.plain) { if (!this.plain) {
const res = []; const res: (VNode | string)[] = [];
for (const t of text.split('\n')) { for (const t of text.split('\n')) {
res.push(h('br')); res.push(h('br'));
res.push(t); res.push(t);
@ -317,12 +317,13 @@ export default defineComponent({
} }
default: { default: {
console.error('unrecognized ast type:', token.type); // eslint-disable-next-line @typescript-eslint/no-explicit-any
console.error('unrecognized ast type:', (token as any).type);
return []; return [];
} }
} }
})); }).flat(Infinity) as (VNode | string)[];
// Parse ast to DOM // Parse ast to DOM
return h('span', genEl(ast)); return h('span', genEl(ast));

View File

@ -123,7 +123,7 @@ export function lessThan(xs: number[], ys: number[]): boolean {
* Returns the longest prefix of elements that satisfy the predicate * Returns the longest prefix of elements that satisfy the predicate
*/ */
export function takeWhile<T>(f: Predicate<T>, xs: T[]): T[] { export function takeWhile<T>(f: Predicate<T>, xs: T[]): T[] {
const ys = []; const ys: T[] = [];
for (const x of xs) { for (const x of xs) {
if (f(x)) { if (f(x)) {
ys.push(x); ys.push(x);

View File

@ -1,42 +1,62 @@
export function collectPageVars(content) { interface StringPageVar {
const pageVars = []; name: string,
const collect = (xs: any[]) => { type: 'string',
value: string
}
interface NumberPageVar {
name: string,
type: 'number',
value: number
}
interface BooleanPageVar {
name: string,
type: 'boolean',
value: boolean
}
type PageVar = StringPageVar | NumberPageVar | BooleanPageVar;
export function collectPageVars(content): PageVar[] {
const pageVars: PageVar[] = [];
const collect = (xs: any[]): void => {
for (const x of xs) { for (const x of xs) {
if (x.type === 'textInput') { if (x.type === 'textInput') {
pageVars.push({ pageVars.push({
name: x.name, name: x.name,
type: 'string', type: 'string',
value: x.default || '' value: x.default || '',
}); });
} else if (x.type === 'textareaInput') { } else if (x.type === 'textareaInput') {
pageVars.push({ pageVars.push({
name: x.name, name: x.name,
type: 'string', type: 'string',
value: x.default || '' value: x.default || '',
}); });
} else if (x.type === 'numberInput') { } else if (x.type === 'numberInput') {
pageVars.push({ pageVars.push({
name: x.name, name: x.name,
type: 'number', type: 'number',
value: x.default || 0 value: x.default || 0,
}); });
} else if (x.type === 'switch') { } else if (x.type === 'switch') {
pageVars.push({ pageVars.push({
name: x.name, name: x.name,
type: 'boolean', type: 'boolean',
value: x.default || false value: x.default || false,
}); });
} else if (x.type === 'counter') { } else if (x.type === 'counter') {
pageVars.push({ pageVars.push({
name: x.name, name: x.name,
type: 'number', type: 'number',
value: 0 value: 0,
}); });
} else if (x.type === 'radioButton') { } else if (x.type === 'radioButton') {
pageVars.push({ pageVars.push({
name: x.name, name: x.name,
type: 'string', type: 'string',
value: x.default || '' value: x.default || '',
}); });
} else if (x.children) { } else if (x.children) {
collect(x.children); collect(x.children);

View File

@ -55,13 +55,13 @@ export function physics(container: HTMLElement) {
//wallLeft, //wallLeft,
]); ]);
const objEls = Array.from(container.children); const objEls = Array.from(container.children) as HTMLElement[];
const objs = []; const objs: Matter.Body[] = [];
for (const objEl of objEls) { for (const objEl of objEls) {
const left = objEl.dataset.physicsX ? parseInt(objEl.dataset.physicsX) : objEl.offsetLeft; const left = objEl.dataset.physicsX ? parseInt(objEl.dataset.physicsX) : objEl.offsetLeft;
const top = objEl.dataset.physicsY ? parseInt(objEl.dataset.physicsY) : objEl.offsetTop; const top = objEl.dataset.physicsY ? parseInt(objEl.dataset.physicsY) : objEl.offsetTop;
let obj; let obj: Matter.Body;
if (objEl.classList.contains('_physics_circle_')) { if (objEl.classList.contains('_physics_circle_')) {
obj = Matter.Bodies.circle( obj = Matter.Bodies.circle(
left + (objEl.offsetWidth / 2), left + (objEl.offsetWidth / 2),
@ -84,7 +84,7 @@ export function physics(container: HTMLElement) {
} }
); );
} }
objEl.id = obj.id; objEl.id = obj.id.toString();
objs.push(obj); objs.push(obj);
} }
@ -109,10 +109,10 @@ export function physics(container: HTMLElement) {
render.mouse = mouse; render.mouse = mouse;
for (const objEl of objEls) { for (const objEl of objEls) {
objEl.style.position = `absolute`; objEl.style.position = 'absolute';
objEl.style.top = 0; objEl.style.top = '0';
objEl.style.left = 0; objEl.style.left = '0';
objEl.style.margin = 0; objEl.style.margin = '0';
} }
window.requestAnimationFrame(update); window.requestAnimationFrame(update);

View File

@ -2,11 +2,34 @@ import { markRaw, ref } from 'vue';
import { Storage } from './pizzax'; import { Storage } from './pizzax';
import { Theme } from './scripts/theme'; import { Theme } from './scripts/theme';
export const postFormActions = []; interface PostFormAction {
export const userActions = []; title: string,
export const noteActions = []; handler: <T>(form: T, update: (key: unknown, value: unknown) => void) => void;
export const noteViewInterruptors = []; }
export const notePostInterruptors = [];
interface UserAction {
title: string,
handler: (user: UserDetailed) => void;
}
interface NoteAction {
title: string,
handler: (note: Note) => void;
}
interface NoteViewInterruptor {
handler: (note: Note) => unknown;
}
interface NotePostInterruptor {
handler: (note: FIXME) => unknown;
}
export const postFormActions: PostFormAction[] = [];
export const userActions: UserAction[] = [];
export const noteActions: NoteAction[] = [];
export const noteViewInterruptors: NoteViewInterruptor[] = [];
export const notePostInterruptors: NotePostInterruptor[] = [];
// TODO: それぞれいちいちwhereとかdefaultというキーを付けなきゃいけないの冗長なのでなんとかする(ただ型定義が面倒になりそう) // TODO: それぞれいちいちwhereとかdefaultというキーを付けなきゃいけないの冗長なのでなんとかする(ただ型定義が面倒になりそう)
// あと、現行の定義の仕方なら「whereが何であるかに関わらずキー名の重複不可」という制約を付けられるメリットもあるからそのメリットを引き継ぐ方法も考えないといけない // あと、現行の定義の仕方なら「whereが何であるかに関わらずキー名の重複不可」という制約を付けられるメリットもあるからそのメリットを引き継ぐ方法も考えないといけない
@ -266,11 +289,17 @@ type Plugin = {
ast: any[]; ast: any[];
}; };
interface Watcher {
key: string;
callback: (value: unknown) => void;
}
/** /**
* () * ()
*/ */
import lightTheme from '@/themes/l-light.json5'; import lightTheme from '@/themes/l-light.json5';
import darkTheme from '@/themes/d-green-lime.json5'; import darkTheme from '@/themes/d-green-lime.json5';
import { Note, UserDetailed } from 'misskey-js/built/entities';
export class ColdDeviceStorage { export class ColdDeviceStorage {
public static default = { public static default = {
@ -289,7 +318,7 @@ export class ColdDeviceStorage {
sound_channel: { type: 'syuilo/square-pico', volume: 1 }, sound_channel: { type: 'syuilo/square-pico', volume: 1 },
}; };
public static watchers = []; public static watchers: Watcher[] = [];
public static get<T extends keyof typeof ColdDeviceStorage.default>(key: T): typeof ColdDeviceStorage.default[T] { public static get<T extends keyof typeof ColdDeviceStorage.default>(key: T): typeof ColdDeviceStorage.default[T] {
// TODO: indexedDBにする // TODO: indexedDBにする