項目33 null値を型の外側に押しやる
ある値がnullまたはnullでないことが、別の値がnullまたはnullでないことと暗黙的に関連するような設計は避ける
下記のコードはminとmax両方がundefinedになるか、どちらもならない可能性があることを型で表現できていない
code:ts
function extent(nums: Iterable<number>) {
let min, max;
for (const num of nums) {
if (!min) {
min = num;
max = num;
} else {
min = Math.min(min, num);
max = Math.max(max, num);
}
}
}
戻り値の型が(number | undefined)[]となり、利用する側が扱いづらくなる
code:ts
const span = max - min;
// ~~~ ~~~ Object is possibly 'undefined'
解決策
null値をAPIの外側に押しやり、オブジェクトが完全にnullまたは非nullになるようにする
下記のコードは戻り値の型が[number, number] |nullとなり、利用する側が使いやすくなっている
code:ts
function extent(nums: Iterable<number>) {
for (const num of nums) {
if (!minMax) {
} else {
}
}
return minMax;
}
if (range) {
const span = max - min; // OK
}
完全に非nullなクラスを作り、すべての値が利用可能な状態になってからインスタンス化できるような設計にする
code:ts
class UserPosts {
user: UserInfo;
posts: Post[];
constructor(user: UserInfo, posts: Post[]) {
this.user = user;
this.posts = posts;
}
static async init(userId: string): Promise<UserPosts> {
fetchUser(userId),
fetchPostsForUser(userId)
]);
return new UserPosts(user, posts);
}
getUserName() {
return this.user.name;
}
}