안녕하세요!
질문을 노션으로 정리해서 질문하는게 더 좋아 보여 노션을 이용하여 질문 드립니다!
// 외부 API, (node_modeuls/...)
declare type SelectPropertyResponse = {
id: StringRequest;
name: StringRequest;
color: SelectColor;
};
// ...
export declare type GetPageResponse = {
parent: {
type: "database_id";
database_id: IdRequest;
} | {
type: "page_id";
page_id: IdRequest;
} | {
type: "workspace";
workspace: true;
};
properties: Record<string, {
type: "number";
number: number | null;
id: string;
} | {
type: "url";
url: string | null;
id: string;
} | {
type: "select";
select: SelectPropertyResponse | null;
id: string;
} | {
type: "multi_select";
multi_select: Array<SelectPropertyResponse>;
id: string;
} | {
type: "date";
date: DateResponse | null;
id: string;
} | {
type: "email";
email: string | null;
id: string;
} | {
type: "phone_number";
phone_number: string | null;
id: string;
} | {
type: "checkbox";
checkbox: boolean;
id: string;
} | {
type: "files";
files: Array<{
file: {
url: string;
expiry_time: string;
};
name: StringRequest;
type?: "file";
} | {
external: {
url: TextRequest;
};
name: StringRequest;
type?: "external";
}>;
id: string;
} | {
type: "created_by";
created_by: PartialUserObjectResponse;
id: string;
} | {
type: "created_time";
created_time: string;
id: string;
} | {
type: "last_edited_by";
last_edited_by: PartialUserObjectResponse;
id: string;
} | {
type: "last_edited_time";
last_edited_time: string;
id: string;
} | {
type: "formula";
formula: {
type: "string";
string: string | null;
} | {
type: "date";
date: DateResponse | null;
} | {
type: "number";
number: number | null;
} | {
type: "boolean";
boolean: boolean | null;
};
id: string;
} | {
type: "title";
title: Array<RichTextItemResponse>;
id: string;
} | {
type: "rich_text";
rich_text: Array<RichTextItemResponse>;
id: string;
} | {
type: "people";
people: Array<PartialUserObjectResponse>;
id: string;
} | {
type: "relation";
relation: Array<{
id: string;
}>;
id: string;
} | {
type: "rollup";
rollup: {
type: "number";
number: number | null;
function: RollupFunction;
} | {
type: "date";
date: DateResponse | null;
function: RollupFunction;
} | {
type: "array";
array: Array<{
type: "title";
title: Array<RichTextItemResponse>;
} | {
type: "rich_text";
rich_text: Array<RichTextItemResponse>;
} | {
type: "people";
people: Array<PartialUserObjectResponse>;
} | {
type: "relation";
relation: Array<{
id: string;
}>;
}>;
function: RollupFunction;
};
id: string;
}>;
icon: {
type: "emoji";
emoji: EmojiRequest;
} | null | {
type: "external";
external: {
url: TextRequest;
};
} | null | {
type: "file";
file: {
url: string;
expiry_time: string;
};
} | null;
cover: {
type: "external";
external: {
url: TextRequest;
};
} | null | {
type: "file";
file: {
url: string;
expiry_time: string;
};
} | null;
created_by: {
id: IdRequest;
object: "user";
};
last_edited_by: {
id: IdRequest;
object: "user";
};
object: "page";
id: string;
created_time: string;
last_edited_time: string;
archived: boolean;
url: string;
} | {
object: "page";
id: string;
};
우선 GetPageResponse 타입으로 2개의 유니온 타입으로 구성되어 있습니다.
저 같은 경우 전자의 타입을 이용하고자 합니다.

if ('properties' in postPage) {
const properties = postPage['properties'];
const _title = properties['title'];
const _tags = properties['tags'];
if (_title.type === 'title') {
title = _title.title[0].plain_text;
}
if (_tags.type === 'multi_select') {
tags = _tags.multi_select;
}
// ...
}
// 사용
const post: Post = {
id: postPage.id,
title,
tags,
description: postPage.properties.description['rich_text'][0]['plain_text'],
createdTime: new Date(postPage.created_time).toLocaleDateString(),
};
여기서 궁금한게, postPage 도 union 타입 형태로 있어 타입 가드로 타입을 좁혔고, 이후 세부 속성도 title, tags, (description, createdTime 등도 설정해야함) 위 코드 처럼 하나하나 다 지정해야하는지 궁금합니다.
⇒ 해당 형태가 다른 곳에서도 사용하기 때문에 만약 필요하면, parse 하는 함수를 따로 빼야하나 궁금합니다.
외부 API 에 SelectPropertyResponse 이 declare 로 지정되어 있는데 해당 타입을 제 코드 상에서도 사용해야하는데 해당타입이 export 되어있지 않습니다.
이럴 경우 그냥 제가 따로 타입을 선언해서 사용하는게 좋은지, 아니면 더 좋은 방법이 있는지 궁금합니다!
결국 GetPageResponse 의 properties 타입이 여러 union 타입으로 지정되어 있어 해당 타입을 타입가드로 하는 방법이 최선인지 궁금합니다
다른 방법은 as 로 강제로 타입을 지정해야하는지 생각했는데.. 이런 경우 좋은 방법이 있는지 궁금합니다
// 제가 구상한 방법??
// 외부 API 에서 가져와야하는지, 외부 API 에서 참고해서 새로운 타입을 만들어야하는지...
declare type SelectPropertyResponse = { // 정상 타입이라고 가정!
id: StringRequest;
name: StringRequest;
color: SelectColor;
};
export type MultiSelectType = {
type: 'multi_select';
multi_select: {
options: Array<SelectPropertyResponse>;
};
id: string;
name: string;
};
// 사용하는 곳에서
const tags = (tagsDatabase.properties.tags as Multi_Select).multi_select.options;