Typescript에서 Predicate Combinator 사용
19918 단어 typescript
문제:
술어 함수가 너무 많이 확인하고 있으며 다음보다 더 많은 일을 담당하고 있습니다.
enum UserRole {
Administrator = 1,
Editor = 2,
Subscriber = 3,
Writer = 4,
}
interface User {
username: string;
age: number;
role: UserRole;
}
const users = [
{ username: "John", age: 25, role: UserRole.Administrator },
{ username: "Jane", age: 7, role: UserRole.Subscriber },
{ username: "Liza", age: 18, role: UserRole.Writer },
{ username: "Jim", age: 16, role: UserRole.Editor },
{ username: "Bill", age: 32, role: UserRole.Editor },
];
const greaterThen17AndWriterOrEditor = users.filter((user: User) => {
return (
user.age > 17 &&
(user.role === UserRole.Writer || user.role === UserRole.Editor)
);
});
const greaterThen5AndSubscriberOrWriter = users.filter((user: User) => {
return user.age > 5 && user.role === UserRole.Writer;
});
해결책:
술어 결합자를 사용하기 시작해야 합니다. 코드 가독성과 재사용 가능성이 높아집니다.
type PredicateFn = (value: any, index?: number) => boolean;
type ProjectionFn = (value: any, index?: number) => any;
function or(...predicates: PredicateFn[]): PredicateFn {
return (value) => predicates.some((predicate) => predicate(value));
}
function and(...predicates: PredicateFn[]): PredicateFn {
return (value) => predicates.every((predicate) => predicate(value));
}
function not(...predicates: PredicateFn[]): PredicateFn {
return (value) => predicates.every((predicate) => !predicate(value));
}
조합하여 사용하실 수 있습니다.
const isWriter = (user: User) => user.role === UserRole.Writer;
const isEditor = (user: User) => user.role === UserRole.Editor;
const isGreaterThan17 = (user: User) => user.age > 17;
const isGreaterThan5 = (user: User) => user.age > 5;
const greaterThan17AndWriterOrEditor = users.filter(
and(isGreaterThan17, or(isWriter, isEditor))
);
const greaterThan5AndSubscriberOrWriter = users.filter(
and(isGreaterThan5, isWriter)
);
공장과 더 나은 조건자 결합자
술어 결합자는 너무 많은 변수를 생성하므로 이러한 기능 사이에서 길을 잃기 쉽습니다. 콤비네이터 조건자 함수를 한 번만 사용한다면 좀 더 일반적인 것을 사용하는 것이 좋습니다.
const isWriter = (user: User) => user.role === UserRole.Writer;
const isEditor = (user: User) => user.role === UserRole.Editor;
const isGreaterThan17 = (user: User) => user.age > 17;
const isGreaterThan5 = (user: User) => user.age > 5;
const greaterThan17AndWriterOrEditor = users.filter(
and(isGreaterThan17, or(isWriter, isEditor))
);
const greaterThan5AndSubscriberOrWriter = users.filter(
and(isGreaterThan5, isWriter)
);
결합자 술어 팩토리를 사용하여 이 문제를 해결할 수 있습니다.
const isRole = (role: UserRole) =>
(user: User) => user.role === role;
const isGreaterThan = (age: number) =>
(user: User) => user.age > age;
const greaterThan17AndWriterOrEditor = users.filter(
and(isGreaterThan(17), or(isRole(UserRole.Writer), isRole(UserRole.Editor)))
);
const greaterThan5AndSubscriberOrWriter = users.filter(
and(isGreaterThan(5), isRole(UserRole.Writer))
일부 함수 호출이 동일한 인수로 반복되는 것을 알아차렸을 것입니다. 가장 좋은 옵션은 결합기 술어와 함께 술어 팩토리를 혼합하는 것입니다. 따라서 우리는 두 세계의 장점을 모두 누릴 수 있습니다.
const isRole = (role: UserRole) =>
(user: User) => user.role === role;
const isGreaterThan = (age: number) =>
(user: User) => user.age > age;
const isWriter = isRole(UserRole.Writer)
const greaterThan17AndWriterOrEditor = users.filter(
and(isGreaterThan(17), or(isWriter, isRole(UserRole.Editor)))
);
const greaterThan5AndSubscriberOrWriter = users.filter(
and(isGreaterThan(5), isWriter)
);
이런 식으로 반복 횟수를 줄이고 코드를 깨끗하고 깔끔하게 유지합니다.
Reference
이 문제에 관하여(Typescript에서 Predicate Combinator 사용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/satel/using-predicate-combinators-in-typescript-ijj텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)