Skip to content

Commit

Permalink
Vueファイル内の型エラーを減らす (#1295)
Browse files Browse the repository at this point in the history
Co-authored-by: Hiroshiba <[email protected]>
  • Loading branch information
yamachu and Hiroshiba authored May 17, 2023
1 parent f42d64a commit 32940ea
Show file tree
Hide file tree
Showing 9 changed files with 347 additions and 232 deletions.
408 changes: 209 additions & 199 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
"vite-plugin-node-polyfills": "0.7.0",
"vite-tsconfig-paths": "4.0.5",
"vitest": "0.28.5",
"vue-tsc": "0.40.13",
"vue-tsc": "1.4.2",
"yargs": "17.2.1"
}
}
7 changes: 4 additions & 3 deletions src/components/EngineManageDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,10 @@
"
>
<li
v-for="[feature, value] in Object.entries(
engineManifests[selectedId].supportedFeatures
)"
v-for="(value, feature) in engineManifests[selectedId]
.supportedFeatures !== null
? engineManifests[selectedId].supportedFeatures
: null"
:key="feature"
:class="value ? '' : 'text-warning'"
>
Expand Down
10 changes: 9 additions & 1 deletion src/components/HotkeySettingDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,15 @@ const hotkeyFilter = ref("");
const hotkeySettings = computed(() => store.state.hotkeySettings);
const hotkeyColumns = ref([
// FIXME: satisfiesを使うなどで型を表現したい
const hotkeyColumns = ref<
{
name: string;
align: "left" | "right" | "center" | undefined;
label: string;
field: string;
}[]
>([
{
name: "action",
align: "left",
Expand Down
32 changes: 22 additions & 10 deletions src/components/LibraryPolicy.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
<template v-if="engineInfos.size > 1">
<q-separator spaced v-if="engineIndex > 0" />
<q-item-label header>{{
engineInfos.get(engineId).name
mapUndefinedPipe(engineInfos.get(engineId), (v) => v.name)
}}</q-item-label>
</template>
<template
v-for="([, characterInfo], characterIndex) in engineInfos.get(
engineId
).characterInfos"
v-for="([, characterInfo], characterIndex) in mapUndefinedPipe(
engineInfos.get(engineId),
(v) => v.characterInfos
)"
:key="characterIndex"
>
<q-item
Expand Down Expand Up @@ -52,18 +53,28 @@
</div>
<div class="text-subtitle">
{{
engineInfos
.get(selectedInfo.engine)
.characterInfos.get(selectedInfo.character).metas.speakerName
mapUndefinedPipe(
engineInfos.get(selectedInfo.engine),
(v) => v.characterInfos,
(v) => mapUndefinedPipe(selectedInfo, (i) => v.get(i.character)),
(v) => v.metas.speakerName
)
}}
</div>
<div
class="markdown"
v-html="
convertMarkdown(
engineInfos
.get(selectedInfo.engine)
.characterInfos.get(selectedInfo.character).metas.policy
undefinedToDefault(
'',
mapUndefinedPipe(
engineInfos.get(selectedInfo.engine),
(v) => v.characterInfos,
(v) =>
mapUndefinedPipe(selectedInfo, (i) => v.get(i.character)),
(v) => v.metas.policy
)
)
)
"
></div>
Expand All @@ -77,6 +88,7 @@ import { computed, ref } from "vue";
import { useStore } from "@/store";
import { useMarkdownIt } from "@/plugins/markdownItPlugin";
import { EngineId, SpeakerId } from "@/type/preload";
import { mapUndefinedPipe, undefinedToDefault } from "@/helpers/map";
type DetailKey = { engine: EngineId; character: SpeakerId };
Expand Down
15 changes: 2 additions & 13 deletions src/components/MenuBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</template>

<script setup lang="ts">
import { ref, computed, ComputedRef, watch } from "vue";
import { ref, computed, watch } from "vue";
import { useQuasar } from "quasar";
import { useStore } from "@/store";
import MenuButton from "@/components/MenuButton.vue";
Expand Down Expand Up @@ -63,18 +63,7 @@ export type MenuItemButton = MenuItemBase<"button"> & {
disableWhenUiLocked: boolean;
};
export type MenuItemCheckbox = MenuItemBase<"checkbox"> & {
checked: ComputedRef<boolean>;
onClick: () => void;
disabled?: boolean;
disableWhenUiLocked: boolean;
};
export type MenuItemData =
| MenuItemSeparator
| MenuItemRoot
| MenuItemButton
| MenuItemCheckbox;
export type MenuItemData = MenuItemSeparator | MenuItemRoot | MenuItemButton;
export type MenuItemType = MenuItemData["type"];
Expand Down
5 changes: 0 additions & 5 deletions src/components/MenuItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@
:disable="menudata.disabled"
@click="menudata.onClick"
>
<q-item-section v-if="menudata.type === 'checkbox'" side class="q-pr-sm">
<q-icon v-if="menudata.checked" name="check" />
<q-icon v-else />
</q-item-section>

<q-item-section
avatar
v-if="'icon' in menudata && menudata.icon != undefined"
Expand Down
37 changes: 37 additions & 0 deletions src/helpers/map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
export function mapUndefinedPipe<T, U1>(
source: T | undefined,
fn1: (_: NonNullable<T>) => U1 | undefined
): U1 | undefined;
export function mapUndefinedPipe<T, U1, U2>(
source: T | undefined,
fn1: (_: NonNullable<T>) => U1 | undefined,
fn2: (_: NonNullable<U1>) => U2 | undefined
): U2 | undefined;
export function mapUndefinedPipe<T, U1, U2, U3>(
source: T | undefined,
fn1: (_: NonNullable<T>) => U1 | undefined,
fn2: (_: NonNullable<U1>) => U2 | undefined,
fn3: (_: NonNullable<U2>) => U3 | undefined
): U3 | undefined;
/**
* 一連の関数を実行する。途中でundefinedを返すとその後undefinedを返す。
*/
// eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any
export function mapUndefinedPipe(source: any, ...fn: Function[]) {
return fn.reduce((prev, curr) => {
if (prev === undefined) {
return undefined;
}
return curr(prev);
}, source);
}

export const undefinedToDefault = <T>(
defaultValue: T,
maybeValue: T | undefined
): T => {
if (maybeValue === undefined) {
return defaultValue;
}
return maybeValue;
};
63 changes: 63 additions & 0 deletions tests/unit/lib/map.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { describe, expect, it } from "vitest";

import { mapUndefinedPipe, undefinedToDefault } from "@/helpers/map";

type DummyType = {
outerValue?: {
innerValue?: string;
};
};

describe("mapUndefinedPipe", () => {
it("値をunwrap出来る", () => {
const key = "test";
const innerValue = "value";
const value: DummyType = {
outerValue: {
innerValue,
},
};
const map = new Map<string, DummyType>([[key, value]]);
expect(
mapUndefinedPipe(
map.get(key),
(v) => v.outerValue,
(v) => v.innerValue
)
).toEqual(innerValue);
});

it("途中でundefinedを返すとその後undefinedを返す", () => {
const key = "test";
const value: DummyType = {
outerValue: {
innerValue: undefined,
},
};
const map = new Map<string, DummyType>([[key, value]]);
expect(
mapUndefinedPipe(
map.get(key),
(v) => v.outerValue,
(v) => v.innerValue
)
).toBeUndefined();
});
});

describe("undefinedToDefault", () => {
it("値がある時はそのまま返す", () => {
const actualValue = "value";
expect(undefinedToDefault("test", actualValue)).toEqual(actualValue);
});

it("値がない時はdefaultValueを返す", () => {
const defaultValue = "test";
expect(undefinedToDefault(defaultValue, undefined)).toEqual(defaultValue);
});

it("undefinedのみを値がない状態とみなす", () => {
const defaultValue = "test";
expect(undefinedToDefault(defaultValue, null)).toBeNull();
});
});

0 comments on commit 32940ea

Please sign in to comment.