Template Literal Types
関連
v4.3で入った改善
分けて理解する必要はないので、この名称はほぼ不要

union
これもdistributeされるのね

tstype VerticalAlignment = "top" | "middle" | "bottom";
type HorizontalAlignment = "left" | "center" | "right";
// Takes
// | "top-left" | "top-center" | "top-right"
// | "middle-left" | "middle-center" | "middle-right"
// | "bottom-left" | "bottom-center" | "bottom-right"
declare function setAlignment(value: `${VerticalAlignment}-${HorizontalAlignment}`): void;
setAlignment("top-left"); // works!
setAlignment("top-middel"); // error!
setAlignment("top-pot"); // error! but good doughnuts if you're ever in Seattle
3*3で9個のパターンのみをみたす
例
tsA extends `foo${infer B}baz` ? B : never
型Aが foohogebaz
なら、型Bは hoge
数値リテラルの文字列化
tsN extends number ? `${N} : never
${}
の中に、型を書ける
tstype HelloStr = `Hello, ${string}`;
書ける型は以下
'string | number | bigint | boolean | null | undefined'
as const
を付けた時の挙動
tsconst world = 'world';
const str1 = `Hello, ${world}!`; // string
const str2 = `Hello, ${world}!` as const; // `Hello, ${string}!`
keyof T
とかと組み合わせる時は、 string &
も付けてあげないといけない
template literal typesに入れられるのが、stringとかnumberとかだから
キモいなと思ってた理由が、「型安全ではない」点だったので、そこが解消されている
tstype PropEventSource<T> = {
on<K extends string & keyof T>(
eventName: `${K}Changed`,
callback: (newValue: T[K]) => void
): void;
};
/// Create a "watched object" with an 'on' method
/// so that you can watch for changes to properties.
declare function makeWatchedObject<T>(obj: T): T & PropEventSource<T>;
const person = makeWatchedObject({
firstName: 'Homer',
age: 42, // give-or-take
location: 'Springfield'
});
person.on('firstNameChanged', () => {
console.log(`firstName was changed!`);
});
// works! 'newName' is typed as 'string'
person.on('firstNameChanged', newName => {
// 'newName' has the type of 'firstName'
console.log(`new name is ${newName.toUpperCase()}`);
});
// works! 'newAge' is typed as 'number'
person.on('ageChanged', newAge => {
if (newAge < 0) {
console.log('warning! negative age');
}
});
題材
usecase
HTMLのquerySelector
routing
next
parse
型レベルSQL DB
型レベルSQL Interpreter
麻雀
参考
型レベルで、文字列を整数に変換する
v4.3の変更