type Vals<T> = T[keyof T];
export type PathsOf<T> = T extends object ? Vals<{ [P in keyof T]-?: [] | [P] | [P, ...PathsOf<T[P]>] }> : [];
출처: https://stackoverflow.com/questions/58434389/typescript-deep-keyof-of-a-nested-object
"-?"가 뭔지 몰라서 헷갈렸는데
https://www.typescriptlang.org/docs/handbook/2/mapped-types.html
Typescript 공식 문서에 의하면
// Removes 'optional' attributes from a type's properties
type Concrete<Type> = {
[Property in keyof Type]-?: Type[Property];
};
type MaybeUser = {
id: string;
name?: string;
age?: number;
};
type User = Concrete<MaybeUser>;
/* type User = {
id: string;
name: string;
age: number;
} */
optional인 부분을 required로 바꿔주는 코드다.
type 현수타입 = {
name: string
age: number
}
type 민수타입 = {
name: string
age: number
friend: {
name: string
age: number
}[]
}
const 현수: 현수타입 = {
name: "현수",
age: 28
}
const 민수: 민수타입 = {
name: "민수",
age: 27
friend: [
{
name: "철수",
age: 27
}
]
}
// 제네릭 타입 지정
function helloUser<T>(user: T): string {
return `안녕하세요 ${user.name}님!`
}
console.log(helloUser<현수타입>(현수))
console.log(helloUser<민수타입>(민수))
interface TableType<T> {
field: { title: string; key: keyof T }[];
rows: T[];
}
function Table<T>(props: TableType<T>): React.ReactElement {
return (
<div>
...
</div>
);
}
export default function App() {
type CurrentUserType = {
name: string;
age: number;
};
const currUsers: CurrentUserType[] = [
{
name: "현수",
age: 28
},
{
name: "민수",
age: 25
},
{
name: "철수",
age: 26
}
];
return (
<div className="App">
//이렇게 컴포넌트에도 제네릭 타입을 넘겨 줄 수 있습니다~!
<Table<CurrentUserType>
field={[
{ title: "이름", key: "name" },
{ title: "나이", key: "age" }
]}
rows={currUsers}
/>
</div>
);
}