TypeScript에서 단일 속성을 옵션으로 설정
TypeScript 2.2에서는...
예를 들어 다음과 같은 유형의 사람이 있다고 가정합니다.
interface Person {
name: string;
hometown: string;
nickname: string;
}
또한 사용자를 반환하지만 닉네임이 필요 없는 함수를 만들고 싶습니다.
function makePerson(input: ???): Person {
return {...input, nickname: input.nickname || input.name};
}
의 유형은 무엇입니까?input
? 와 같은 타입을 동적으로 지정하는 방법을 찾고 있습니다.Person
을 제외하고nickname
는 옵션입니다(nickname?: string | undefined
지금까지 알아낸 것 중 가장 가까운 것은 다음과 같습니다.
type MakePersonInput = Partial<Person> & {
name: string;
hometown: string;
}
다만, 옵션 타입이 아닌, 필요한 타입을 모두 지정해야 하기 때문에, 이 타입을 찾고 있는 것은 아닙니다.
이와 같은 작업을 수행할 수도 있습니다. 일부 키만 사용할 수 있습니다.
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
interface Person {
name: string;
hometown: string;
nickname: string;
}
type MakePersonInput = PartialBy<Person, 'nickname'>
이것은 타입 스크립트 3.5+ 옵션 유틸리티 타입입니다.
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
// and your use case
type MakePersonInput = Optional<Person, 'nickname'>
// and if you wanted to make the hometown optional as well
type MakePersonInput = Optional<Person, 'hometown' | 'nickname'>
플러그 앤 플레이 솔루션에 대해서는, 다음과 같은 뛰어난 패키지의 사용을 검토해 주세요.
npm i utility-types --save
다음으로 다음 항목을 사용합니다.
import { Optional } from 'utility-types';
type Person = {
name: string;
hometown: string;
nickname: string;
}
type PersonWithOptionalNickname = Optional<Person, 'nickname'>;
// Expect:
//
// type PersonWithOptionalNickname {
// name: string;
// hometown: string;
// nickname?: string;
// }
업데이트:
TypeScript 2.8 에서는, 조건 타입에 의해서 한층 더 간단하게 서포트되고 있습니다.지금까지 이 또한 이전 구현보다 더 신뢰할 수 있는 것으로 보입니다.
type Overwrite<T1, T2> = {
[P in Exclude<keyof T1, keyof T2>]: T1[P]
} & T2;
interface Person {
name: string;
hometown: string;
nickname: string;
}
type MakePersonInput = Overwrite<Person, {
nickname?: string;
}>
function makePerson(input: MakePersonInput): Person {
return {...input, nickname: input.nickname || input.name};
}
아까처럼MakePersonInput
는 다음과 같습니다.
type MakePersonInput = {
name: string;
hometown: string;
} & {
nickname?: string;
}
구식:
TypeScript 2.4.1에서는 GitHub 사용자 ahejlsberg가 스레드 온 타입 감산 방식으로 제안한 다른 옵션이 있는 것 같습니다.https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-307871458
type Diff<T extends string, U extends string> = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T];
type Overwrite<T, U> = { [P in Diff<keyof T, keyof U>]: T[P] } & U;
interface Person {
name: string;
hometown: string;
nickname: string;
}
type MakePersonInput = Overwrite<Person, {
nickname?: string
}>
function makePerson(input: MakePersonInput): Person {
return {...input, nickname: input.nickname || input.name};
}
인텔리센스에 따르면MakePersonInput
는 다음과 같습니다.
type MakePersonInput = {
name: string;
hometown: string;
} & {
nickname?: string;
}
좀 웃기게 생겼지만 확실히 해냈죠.
안 좋은 쪽으로, 난 그걸 바라볼 필요가 있을 거야Diff
어떻게 작동하는지 알기 전에 잠시 입력해 주세요.
type-fest 패키지에는 유틸리티가 있습니다.SetOptional
- https://github.com/sindresorhus/type-fest/blob/main/source/set-optional.d.ts
import { SetOptional } from 'type-fest';
type PersonWithNicknameOptional = SetOptional<Person, 'nickname'>
라이브러리가 잘 관리되어 있고 최신 버전의 타이프 스크립트를 지원합니다.타이프 스크립트 프로젝트 IMO에 추가할 가치가 있습니다.
최신 버전의 타이프스크립트를 사용하는 경우 간단한 해결책은 다음과 같습니다.
function makePerson(input: Omit<Person, 'nickname'> & { nickname?: string }): Person {
return {...input, nickname: input.nickname || input.name};
}
기본적으로 인터페이스에서 "nickname" 속성을 삭제하고 옵션으로 다시 추가합니다.
원래의 인터페이스와 동기하고 싶은 경우는, 다음의 조작을 실행할 수 있습니다.
Omit<Person, 'nickname'> & Partial<Pick<Person, 'nickname'>>
원래 인터페이스에서 "private" 프로펠러를 변경하면 경고가 표시됩니다.
네, 실제로 설명하고 있는 것은, 2개의 다른 「타입」의 사람(즉, 사람 타입)입니다.평범한 사람과 별명이 붙은 사람.
interface Person {
name: string;
hometown: string;
}
interface NicknamedPerson extends Person {
nickname: string;
}
그런 다음 닉네임을 가진 사람이 아니라 단순히 사람을 원하는 경우에는 Person 인터페이스를 구현하면 됩니다.
1개의 사용자 인터페이스만을 유지할 필요가 있는 경우는, 닉네임이 없는 사용자에 대해서 다른 실장을 실시하는 방법도 있습니다.
interface Person {
name: string;
hometown: string;
nickname: string;
}
class NicknamedPerson implements Person {
constructor(public name: string, public hometown: string, public nickname: string) {}
}
class RegularPerson implements Person {
nickname: string;
constructor(public name: string, public hometown: string) {
this.nickname = name;
}
}
makePerson(input): Person {
if(input.nickname != null) {
return new NicknamedPerson(input.name, input.hometown, input.nickname);
} else {
return new RegularPerson(input.name, input.hometown);
}
}
이렇게 하면 닉네임을 할당하고(닉네임이 없는 경우 사용자 이름만 해당) 사용자 인터페이스의 계약을 유지할 수 있습니다.이것은, 실제로, 인터페이스를 사용하는 방법에 관한 것입니다.닉네임을 가진 사람에 대해 코드가 신경을 쓰나요?그렇지 않다면, 첫 번째 제안이 더 나을 것입니다.
여러 번 조사해 본 결과, TypeScript에서는 불가능하다고 생각됩니다.아직이다. 하지만 확산/휴식 타입이 착륙할 때, 나는 그것이 구문을 따라 무엇인가가 될 것이라고 생각한다.{ ...Person, nickname?: string }
.
지금은 좀 더 자세한 접근법으로 필요한 속성을 선언했습니다.
type MakePersonInput = Partial<Person> & {
name: string;
hometown: string;
};
function makePerson(input: MakePersonInput): Person {
return {...input, nickname: input.nickname || input.name};
}
.MakePersonInput
i whenever whenever whenever whenever whenever whenever whenever whenever whenever whenever whenever whenever whenever whenever Person
수 ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ.그것은, 에러 타입의 원인이 되기 때문입니다.makePerson
.
언급URL : https://stackoverflow.com/questions/43159887/make-a-single-property-optional-in-typescript
'programing' 카테고리의 다른 글
Axios가 내 요청 매개 변수를 인코딩하지 못하도록 하려면 어떻게 해야 합니까? (0) | 2023.03.28 |
---|---|
java.displaces를 클릭합니다.InlawalStateException:클래스를 조사하지 못했습니다. (0) | 2023.03.28 |
형식 스크립트에서 Enum을 제한된 키 유형으로 사용 (0) | 2023.03.28 |
반응 선택 비활성화 옵션 (0) | 2023.03.28 |
컴포넌트를 반응시키기 위한 전달 (0) | 2023.03.28 |