/** nums를 변경하지 않습니다. */
function sort(nums: number[]) {
/* ... */
} // bad!!
function sort(nums: readonly number[]) { /* ... */ } // good!!!
interface UserInfo {
name: string;
}
interface Post {
post: string;
}
declare function fetchUser(userId: string): Promise<UserInfo>;
declare function fetchPostsForUser(userId: string): Promise<Post[]>;
class UserPosts {
user: UserInfo | null;
posts: Post[] | null;
constructor() {
this.user = null;
this.posts = null;
}
async init(userId: string) {
return Promise.all([
async () => (this.user = await fetchUser(userId)),
async () => (this.posts = await fetchPostsForUser(userId)),
]);
}
getUserName() {
return this.user.name;
}
}
위에서 네트워크가 요청되는 동안 속성값이 불확실해지기 때문에 버그가 생길수 있습니다.
interface UserInfo { name: string }
interface Post { post: string }
declare function fetchUser(userId: string): Promise<UserInfo>;
declare function fetchPostsForUser(userId: string): Promise<Post[]>;
class UserPosts {
user: UserInfo;
posts: Post[];
constructor(user: UserInfo, posts: Post[]) {
this.user = user;
this.posts = posts;
}
static async init(userId: string): Promise<UserPosts> {
const [user, posts] = await Promise.all([
fetchUser(userId),
fetchPostsForUser(userId)
]);
return new UserPosts(user, posts);
}
getUserName() {
return this.user.name;
}
}
필요한 데이터가 모두 준비된 후에 클래스를 만들도록 바꾸면 해결할 수 있습니다.
-유니온 타입의 속성을 여러 개 가지는 인터페이스에서는 속성 간의 관계가 분명하지 않기 때문에 실수가 자주 발생하므로 주의해야 합니다.
-유니온의 인터페이스보다 인터페이스의 유니온이 더 정확하고 타입스트립트가 이해하기도 좋습니다.
type FillPaint = unknown;
type LinePaint = unknown;
type PointPaint = unknown;
type FillLayout = unknown;
type LineLayout = unknown;
type PointLayout = unknown;
interface FillLayer {
type: 'fill';
layout: FillLayout;
paint: FillPaint;
}
interface LineLayer {
type: 'line';
layout: LineLayout;
paint: LinePaint;
}
interface PointLayer {
type: 'paint';
layout: PointLayout;
paint: PointPaint;
}
type Layer = FillLayer | LineLayer | PointLayer;
function drawLayer(layer: Layer) {
if (layer.type === 'fill') {
const {paint} = layer; // Type is FillPaint
const {layout} = layer; // Type is FillLayout
} else if (layer.type === 'line') {
const {paint} = layer; // Type is LinePaint
const {layout} = layer; // Type is LineLayout
} else {
const {paint} = layer; // Type is PointPaint
const {layout} = layer; // Type is PointLayout
}
}
<이펙티브 타입스크립트> (댄 밴더캅 지음, 장원호 옮김, 인사이트, 2021)