Skip to content

Instantly share code, notes, and snippets.

@polidog
Last active November 16, 2020 12:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save polidog/cca522183f744ec6ed0130a2eae60c9d to your computer and use it in GitHub Desktop.
Save polidog/cca522183f744ec6ed0130a2eae60c9d to your computer and use it in GitHub Desktop.
Roleによって動的にメソッドを付け替える
interface UserData {
firstName: string
lastName: string
role: 'user' | 'admin'
age: number
}
interface UserMethods {
name: () => string
}
interface AdminMethod {
removeAdmin: () => void,
}
type User = UserData & UserMethods
type Admin = UserData & UserMethods & AdminMethod
const fetchUser = ():UserData => {
// APIコールを想定
return {
firstName: 'Ryota',
lastName: 'Mochizuki',
role: 'admin',
age: 35
}
}
const attachUserMethod = (userData: UserData):User => {
return Object.assign<UserData, UserMethods>(userData, {
name: function() {
return `${userData.firstName} ${userData.lastName}`
}
})
}
const attachAdminMethod = (userData: UserData):Admin => {
if (userData.role !== 'admin') {
throw new Error('role error')
}
return Object.assign<User, AdminMethod>(attachUserMethod(userData), {
removeAdmin() {
return attachUserMethod({...userData, role: 'user'})
}
})
}
const attach = (userData: UserData) => {
switch(userData.role) {
case 'admin':
return attachAdminMethod(userData)
case 'user':
return attachUserMethod(userData)
default:
throw new Error('unsupport role')
break;
}
}
const getUser = ():User|Admin => {
return attach(fetchUser())
}
const admin = getUser() as Admin
admin.firstName = 'Taro'
const user = admin.removeAdmin()
console.log(user, admin)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment