検索条件
お知らせ
現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。
TypeScriptをぼちぼちやってきた中で、型推論が素直に決まらないみたいな所が出てきたので書き置きとして残しておきます
具体的には何かしらの関数を通して処理を隠蔽すると上手くいかなくなるケースがあります
検査関数的なものを通した場合に、後続処理で期待通り型が推論されなくなるケースです
type HogePiyo = 'hoge' | 'piyo';
type InputProps<ValueT> = {
value: ValueT;
error: string;
};
const required = (val: string) => {
return val === '';
};
const registerHogePiyo = (value: HogePiyo) => {
console.log('register', value);
};
const input: InputProps<HogePiyo | ''> = {
value: '',
error: '',
};
if (required(input.value)) {
input.error = 'ERR';
console.error(input.error);
} else {
// ここでは input.value は 'hoge' | 'piyo' となるはずだが
// TSC は 'hoge' | 'piyo' | '' と解釈する
registerHogePiyo(input.value);
}
type HogePiyo = 'hoge' | 'piyo';
type InputProps<ValueT> = {
value: ValueT;
error: string;
hasError: boolean;
};
const required = <ValueT>(obj: InputProps<ValueT | ''>) => {
if (obj.value === '') {
return { value: '', error: '必須入力です', hasError: true };
} else {
return { value: obj.value, error: '', hasError: false };
}
};
const registerHogePiyo = (value: HogePiyo) => {
console.log('register', value);
};
const input: InputProps<HogePiyo | ''> = {
value: '',
error: '',
hasError: false,
};
const result = required(input);
if (result.hasError) {
console.error(result.error);
} else {
// ここでは input.value は 'hoge' | 'piyo' となるはずだが
// TSC は 'hoge' | 'piyo' | '' と解釈する
registerHogePiyo(result.value);
}
export {};
オブジェクトに型判定用のプロパティを生やしas
で型を明示することでクリアしています
type HogePiyo = 'hoge' | 'piyo';
type InputProps<ValueT> = {
value: ValueT;
error: string;
hasError: boolean;
};
const required = <ValueT>(obj: InputProps<ValueT | ''>) => {
if (obj.value === '') {
return { value: '', error: '必須入力です', hasError: true } as {
value: '';
error: string;
hasError: true;
};
} else {
return { value: obj.value, error: '', hasError: false } as {
value: ValueT;
error: string;
hasError: false;
};
}
};
const registerHogePiyo = (value: HogePiyo) => {
console.log('register', value);
};
const input: InputProps<HogePiyo | ''> = {
value: '',
error: '',
hasError: false,
};
const result = required(input);
if (result.hasError) {
console.error(input.error);
} else {
registerHogePiyo(result.value);
}
export {};
- Assertion Functionsを使う方法もあると思いますが、何も考えずAssertion Functionsを書くと次のような弊害があり、積極的に採用しづらいと考えています
- 何もしていなければ基本的にバンドル後のソースコードに出てくる
throw
を書く必要性があり、バンドル後に残っている以上、このthrow
をcatch
する必要性がある
- そもそも論としてAssertion Functionsを書く工数が生まれる
- Assertion Functionsの振る舞いを見ている限り、
as
に限りなく近く、ぶっちゃけas
で書いたほうが楽
- 絶対に
as
を使わず現実的な工数で開発するというのは、割と非現実ではないかという感触があります
- 個人的に型推論はIDEが勝手にやってくれるおかげで楽ができるシステムだと考えているので、型推論の補佐をする仕組みに工数をかけるというのは本末転倒な気がしています
- 品質は大切なことですが、反面で少なくないビジネスには期限もあります
- 品質に寄せすぎた過剰に冗長なコードも、納期に寄せすぎた脆弱性不具合山盛りスパゲティコードもどちらも考えものであり、その辺のバランスが上手くとれるやり方がなんかないかなーと考えることはしばしばあります
Windows 10
Env |
Ver |
PHP |
8.0.2 |
Xdebug |
3.0.2 |
zend_extension="xdebug-3.0.2-8.0-vs16-nts-x86_64"
xdebug.start_with_request=yes
xdebug.mode=debug
別になくてもデバッグは出来る
"php.validate.executablePath": "C:/path/to/php.exe",
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9003
}
]
}
$arr = ['a', 'b', 'c'];
$test1 = '';
$test2 = '';
$test3 = '';
for($idx = 0; count($arr) > $idx; $idx++) {
${'test' . ($idx + 1)} = $arr[$idx];
// $this->{'test' . ($idx + 1)} = $arr[$idx];とするとクラスのプロパティも行ける
}
// $test1 = 'a'
// $test2 = 'b'
// $test3 = 'c'
文字列を編集したりするのに大変便利なやつ。sedやawkの代わりに使える。構文はPerlそのものが使える。なにせPerlなので
-e
- ワンライナーでコードを書くやつ
php -r
やnode -e
と同じ
- Evaluate, Eval, 評価
-n
- 入力の各行に対し処理がかかる
$.
で行番号、$_
で行の文字列を取得できる
while (<>)
相当の処理
-p
- 入力の各行に対し処理を行い、更に
print $_
相当の処理を実行する
-l
- 入力(
$_
)から改行文字を削除し出力に改行を追加する
-a
- 入力の各行に対して
awk
相当の文字列分割処理を行う(autosplit mode with -n or -p)
- 分割した文字は
$F
に配列として入るので次のようにして取得できる
perl -ale 'print "$F[0] - $F[1]'
$#F
を指定すると分割した個数が取れる
-F/pattern/
-a
でsplitするパターンを設定する
- 例えば
-F,
とするとCSVを分割できる
-i[ext]
- ファイルを編集する
- 使用例:
perl -i -pe 's/aaa/xxx/' foo.txt
-i.bak
のように指定するとバックアップファイルが作成される
- このオプションは次に続く文字が解釈されるため、単体で指定する必要がある(
-ipe
のようには使えない)
変数を指定しない場合、基本的に$_
として扱われる
print
- 標準出力に出力
- 単体では
print $_
と同じ挙動をする
$hoge =~ s/foo/bar/
/(.+)/; print $1
- キャプチャした内容を出力
- コマンド例:
echo hoge.jpg | perl -ne '/(.+)./; print $1'
$_
- 基本的に書かなくても補完される
- 例えば
echo aaabbc | perl -ne 's/c/d/; print'
の出力はaaabbd
となる
- その他特殊変数:https://perldoc.jp/docs/perl/5.18.1/perlvar.pod
END{}
- このブロックで囲んだコードは実行時の最後に動作する
-n
, -p
を指定した場合、END{}
は$_
が取れないので渡す場合は$x = $_; END{ print $x }
のように別の変数に代入する必要がある
- https://perldoc.jp/docs/perl/5.38.0/perlmod.pod#BEGIN44-32UNITCHECK44-32CHECK44-32INIT32and32END
一例
ls -l | perl -ale '$F[8] =~ s/\.html//; print "$F[8]";'
1のところが行数なので、ここを変えることで任意の行の文字列を取れる
perl -ne 'print if $. == 1'
echo "foo bar" | perl -pe 's/(?<first>.+) (?<last>.+)/$+{first}-$+{last}/'
unshift
で配列の先頭に値を追加し、END{}
で最後に出力している
cat <<EOF | perl -ne 'unshift @x, $_; END{ print @x }'
aaa
bbb
ccc
EOF
Env |
Ver |
next |
11.1.2 |
typescript |
4.3.4 |
export const useRouter = () => {
return {
route: '/',
pathname: '',
query: '',
asPath: '',
push: jest.fn(),
replace: jest.fn(),
events: {
on: jest.fn(),
off: jest.fn(),
},
beforePopState: jest.fn(() => null),
prefetch: jest.fn(() => null),
};
};