Typescript 인터페이스 기본값
TypeScript에는 다음과 같은 인터페이스가 있습니다.
interface IX {
a: string,
b: any,
c: AnotherType
}
해당 유형의 변수를 선언하고 모든 속성을 초기화합니다.
let x: IX = {
a: 'abc',
b: null,
c: null
}
그런 다음 나중에 init 함수에서 실제 값을 할당합니다.
x.a = 'xyz'
x.b = 123
x.c = new AnotherType()
그러나 개체를 선언할 때 각 속성에 대해 기본값 null 값을 여러 개 지정해야 하는 것은 좋아하지 않습니다.공급하지 않은 속성을 null로 기본 설정하도록 인터페이스에 지시할 수 있습니까?어떻게 하면 이 일을 할 수 있을까요?
let x: IX = {
a: 'abc'
}
컴파일러 에러는 표시되지 않습니다.지금 그게 말해주고 있어
TS2322: 유형 '{}'은 유형 'IX'에 할당할 수 없습니다.유형 '{}'에 속성 'b'가 없습니다.
공급하지 않은 속성을 null로 기본 설정하도록 인터페이스에 지시할 수 있습니까?내가 왜 이걸 할 수 있을까?
아니요. 인터페이스 또는 형식 별칭은 컴파일 시간에만 사용할 수 있으며 기본값에는 런타임 지원이 필요하므로 기본값을 제공할 수 없습니다.
대안
, 되지 않은 로 ", " " 입니다.undefined
자바스크립트옵션으로서 마킹할 수 있습니다.
interface IX {
a: string,
b?: any,
c?: AnotherType
}
에서 작성 시 은 " " " " 입니다.a
:
let x: IX = {
a: 'abc'
};
필요에 따라 값을 지정할 수 있습니다.
x.a = 'xyz'
x.b = 123
x.c = new AnotherType()
인터페이스에서는 기본값을 설정할 수 없지만 옵션 속성을 사용하여 원하는 작업을 수행할 수 있습니다.
인터페이스를 다음과 같이 변경합니다.
interface IX {
a: string,
b?: any,
c?: AnotherType
}
다음 작업을 수행할 수 있습니다.
let x: IX = {
a: 'abc'
}
하여 기본 을 "Default" 에 합니다.x.b
★★★★★★★★★★★★★★★★★」x.c
이 속성들이 설정되지 않은 경우.
@은 @Timar에게 딱 @Timar의 은 @Timar에게 딱 .null
디폴트값(요구된 값)이 있습니다.다른 디폴트값을 사용할 수 있는 또 다른 간단한 솔루션이 있습니다.옵션 인터페이스와 기본값을 포함하는 상수를 정의합니다. 생성자에서 분산 연산자를 사용하여 다음을 설정합니다.options
variable( 변수)
interface IXOptions {
a?: string,
b?: any,
c?: number
}
const XDefaults: IXOptions = {
a: "default",
b: null,
c: 1
}
export class ClassX {
private options: IXOptions;
constructor(XOptions: IXOptions) {
this.options = { ...XDefaults, ...XOptions };
}
public printOptions(): void {
console.log(this.options.a);
console.log(this.options.b);
console.log(this.options.c);
}
}
이 클래스는 다음과 같이 사용할 수 있습니다.
const x = new ClassX({ a: "set" });
x.printOptions();
출력:
set
null
1
클래스를 사용하여 인터페이스를 구현하고 컨스트럭터의 멤버 초기화를 처리할 수 있습니다.
class IXClass implements IX {
a: string;
b: any;
c: AnotherType;
constructor(obj: IX);
constructor(a: string, b: any, c: AnotherType);
constructor() {
if (arguments.length == 1) {
this.a = arguments[0].a;
this.b = arguments[0].b;
this.c = arguments[0].c;
} else {
this.a = arguments[0];
this.b = arguments[1];
this.c = arguments[2];
}
}
}
또 다른 접근법은 공장 기능을 사용하는 것입니다.
function ixFactory(a: string, b: any, c: AnotherType): IX {
return {
a: a,
b: b,
c: c
}
}
그 후, 다음과 같이 할 수 있습니다.
var ix: IX = null;
...
ix = new IXClass(...);
// or
ix = ixFactory(...);
.Partial
매뉴얼에 기재되어 있는 맵유형:https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html
이 예에서는 다음과 같이 됩니다.
interface IX {
a: string;
b: any;
c: AnotherType;
}
let x: Partial<IX> = {
a: 'abc'
}
다음 패턴을 사용합니다.
유형 " " " " 를 만듭니다.Defaults<T>
:
type OptionalKeys<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? K : never }[keyof T];
type Defaults<T> = Required<Pick<T, OptionalKeys<T>>>
옵션/기본값으로 클래스 선언:
// options passed to class constructor
export interface Options {
a: string,
b?: any,
c?: number
}
// defaults
const defaults: Defaults<Options> = {
b: null,
c: 1
};
export class MyClass {
// all options in class must have values
options: Required<Options>;
constructor(options: Options) {
// merge passed options and defaults
this.options = Object.assign({}, defaults, options);
}
}
클래스 인스턴스 만들기:
const myClass = new MyClass({
a: 'hello',
b: true,
});
console.log(myClass.options);
// { a: 'hello', b: true, c: 1 }
인터페이스는 컴파일 시에만 존재하기 때문에 인터페이스에 대한 기본값은 사용할 수 없습니다.
대체 솔루션:
여기에는 XI 인터페이스를 구현하는 개체를 반환하는 공장 방식을 사용할 수 있습니다.
예:
class AnotherType {}
interface IX {
a: string,
b: any,
c: AnotherType | null
}
function makeIX (): IX {
return {
a: 'abc',
b: null,
c: null
}
}
const x = makeIX();
x.a = 'xyz';
x.b = 123;
x.c = new AnotherType();
하여 제가 은 두 가지 로 만든 입니다.AnotherType | null
컴파일러 에러가 발생하지 않게 하려면 이 에러가 필요합니다(이 에러는, null을 속성 c 로 초기화한 예에서도 발생하고 있습니다).
파라미터가 많은 경우 사용자가 특정 순서가 아닌 소수의 파라미터만 삽입할 수 있도록 하는 것이 가장 좋습니다.
예를 들어, 잘못된 관행:
foo(a?, b=1, c=99, d=88, e?)
foo(null, null, null, 3)
실제로 필요한 파라미터보다 먼저 모든 파라미터를 지정해야 하기 때문에 (d)
바람직한 사용 방법은 다음과 같습니다.
foo({d=3})
그 방법은 인터페이스를 통해서입니다.파라미터는 다음과 같은 인터페이스로 정의해야 합니다.
interface Arguments {
a?;
b?;
c?;
d?;
e?;
}
그리고 함수를 다음과 같이 정의합니다.
foo(arguments: Arguments)
인터페이스 변수는 기본값을 가져올 수 없습니다.기본값은 어떻게 정의해야 합니까?
인터페이스 전체에 대해 기본값을 정의합니다.
foo({
a,
b=1,
c=99,
d=88,
e
}: Arguments)
사용자가 합격하면:
foo({d=3})
실제 파라미터는 다음과 같습니다.
{
a,
b=1,
c=99,
d=3,
e
}
인터페이스를 선언하지 않는 다른 옵션은 다음과 같습니다.
foo({
a=undefined,
b=1,
c=99,
d=88,
e=undefined
})
Follow Up: 이전 함수 정의에서는 파라미터 객체의 필드에 대한 기본값을 정의하지만 객체 자체에 대한 기본값은 정의하지 않습니다.따라서 추출 오류가 발생합니다(예:Cannot read property 'b' of undefined
다음의 로부터, 「다음에」, 「다음에」를 참조해 주세요.
foo()
다음 두 가지 해결 방법이 있습니다.
1.
const defaultObject = {a=undefined, b=1, c=99, d=88, e=undefined}
function foo({a=defaultObject.a, b=defaultObject.b, c=defaultObject.c, d=defaultObject.d, e=defaultObject.e} = defaultObject)
function foo(object = {}) {
object = { b=1, c=99, d=88, ...object }
//Continue the function code..
}
폴로업: 타입과 디폴트값이 필요한 경우(인터페이스를 선언하고 싶지 않은 경우) 다음과 같이 기술할 수 있습니다.
function foo(params: {a?: string, b?: number, c?: number, d?: number, e?: string}) {
params = { b:1, c:99, d:88, ...params }
//Continue the function code..
}
나는 내가 도달한 것보다 더 나은 방법을 찾다가 이것을 우연히 발견했다.답을 읽고 시험해 본 결과, 다른 답변이 간결하게 느껴지지 않는 만큼, 제가 하고 있는 것을 게재할 가치가 있다고 생각했습니다.새로운 인터페이스를 설정할 때마다 적은 양의 코드만 작성하면 되는 것이 중요했습니다.나는...로 정했어요
커스텀 범용 deepCopy 함수 사용:
deepCopy = <T extends {}>(input: any): T => {
return JSON.parse(JSON.stringify(input));
};
인터페이스 정의
interface IX {
a: string;
b: any;
c: AnotherType;
}
... 디폴트를 다른 Const로 정의합니다.
const XDef : IX = {
a: '',
b: null,
c: null,
};
다음으로 다음과 같이 초기화합니다.
let x : IX = deepCopy(XDef);
그것만 있으면 돼
하지만..
루트 요소를 커스텀 초기화하려면 deepCopy 함수를 변경하여 커스텀 기본값을 사용할 수 있습니다.기능은 다음과 같습니다.
deepCopyAssign = <T extends {}>(input: any, rootOverwrites?: any): T => {
return JSON.parse(JSON.stringify({ ...input, ...rootOverwrites }));
};
대신 다음과 같이 호출할 수 있습니다.
let x : IX = deepCopyAssign(XDef, { a:'customInitValue' } );
다른 선호하는 딥 카피 방법은 모두 사용할 수 있습니다.얕은 복사만 필요한 경우 Object.assign으로 충분하며 유틸리티는 필요 없습니다.deepCopy
또는deepCopyAssign
기능.
let x : IX = object.assign({}, XDef, { a:'customInitValue' });
이미 알려진 문제
- 이 가장으로 깊이 할당되지는 않지만 수정하는 것은 그리 어렵지 않습니다.
deepCopyAssign
할당하기 전에 유형을 반복하고 확인합니다. - 해석/문자열화 프로세스에 의해 함수 및 참조가 손실됩니다.내 업무에는 그것들이 필요없고 작전부도 필요없었다.
- 커스텀 초기화 값은 실행 시 체크된 IDE 또는 타입에 의해 암시되지 않습니다.
솔루션:
입력 문제를 수정하기 위해 Object.assign 위에 래퍼를 만들었습니다.
export function assign<T>(...args: T[] | Partial<T>[]): T {
return Object.assign.apply(Object, [{}, ...args]);
}
사용방법:
env.base.ts
export interface EnvironmentValues {
export interface EnvironmentValues {
isBrowser: boolean;
apiURL: string;
}
export const enviromentBaseValues: Partial<EnvironmentValues> = {
isBrowser: typeof window !== 'undefined',
};
export default enviromentBaseValues;
env.dev.ts
import { EnvironmentValues, enviromentBaseValues } from './env.base';
import { assign } from '../utilities';
export const enviromentDevValues: EnvironmentValues = assign<EnvironmentValues>(
{
apiURL: '/api',
},
enviromentBaseValues
);
export default enviromentDevValues;
2개의 다른 설정을 사용할 수 있습니다.하나는 옵션 속성(기본값)이 있는 입력으로, 다른 하나는 필수 속성만 있는 입력입니다.이 기능은 다음과 같이 편리하게 사용할 수 있습니다.&
그리고.Required
:
interface DefaultedFuncConfig {
b?: boolean;
}
interface MandatoryFuncConfig {
a: boolean;
}
export type FuncConfig = MandatoryFuncConfig & DefaultedFuncConfig;
export const func = (config: FuncConfig): Required<FuncConfig> => ({
b: true,
...config
});
// will compile
func({ a: true });
func({ a: true, b: true });
// will error
func({ b: true });
func({});
지금 이 상황을 헤쳐나가고 있어.를 사용하다class
대신interface
.
class IX {
a: String = '';
b?: any;
c: Cee = new Cee();
}
class Cee {
c: String = 'c';
e: String = 'e';
}
리액트 컴포넌트에 이게 필요했어요
왼쪽 값이 Null 또는 Undefined인 경우 기본값을 할당하는 Nullish 병합 연산자를 사용할 수 있습니다.
interface IX {
a: string,
b?: any,
c?: AnotherType
}
const ixFunction: React.FC<IX> = (props) => {
console.log(props.b?? "DefaultValue")
}
그러나 이것은 변수를 한 곳에서만 사용하려는 경우에만 작동합니다.
케이스와 용도에 따라 다릅니다.일반적으로 TypeScript에서는 인터페이스의 기본값은 없습니다.
기본값을 사용하지 않는 경우
신고하실 수 있습니다.x
다음과 같이 합니다.
let x: IX | undefined; // declaration: x = undefined
다음으로 init 함수에서 실제 값을 설정할 수 있습니다.
x = {
a: 'xyz'
b: 123
c: new AnotherType()
};
이렇게 해서x
정의되지 않거나 정의할 수 있습니다.undefined
는 오브젝트가 불필요한 경우 기본값을 설정하지 않고 초기화되지 않았음을 나타냅니다.이것은 "쓰레기"를 정의하는 것보다 로지적으로 더 낫다.
개체를 부분적으로 할당하는 경우:
다음과 같은 선택적 속성을 사용하여 유형을 정의할 수 있습니다.
interface IX {
a: string,
b?: any,
c?: AnotherType
}
이 경우 설정만 하면 됩니다.a
은 '아까보다'로되어 있습니다?
, 이며, 「」, 「」, 「」, 「」, 「」를 의미합니다.undefined
디폴트값으로 설정합니다.
아니면 심지어
let x: Partial<IX> = { ... }
그러면 모든 필드가 선택사항이 됩니다.
어떤 경우에도 기본값으로 사용할 수 있습니다.사용 사례에 따라 다릅니다.
또한 기본 속성 값으로 개체를 반환하는 도우미 메서드/함수를 사용할 수 있습니다.이 경우 필요에 따라 발신자 코드가 기본값을 덮어쓸 수 있습니다.그것이 제가 현재 진행 중인 프로젝트에서 같은 질문에 직면했기 때문에 제가 따르고 있는 접근법입니다.이와 같이 기본 속성 값 개체를 코딩하는 것은 일회성 문제이며, 전체 응용 프로그램에서 이 개체를 재사용할 수 있습니다.
또 다른 방법은 https://www.npmjs.com/package/merge 를 사용하는 것입니다.
이것은 마지막 답과 같지만 좀 더 깔끔하다.
머지를 인스톨 합니다.
yarn add -D merge
다음으로 몇 가지 옵션을 사용하여 인터페이스를 만듭니다.
이걸 ㅇㅇㅇㅇㅇㅇㅇㅇㅇ에 요.
./types/index.ts.
export interface ExampleOpts {
opt1: string,
opt2: string,
opt3: string,
}
은 기본 설정 .
수도 , 그 해서, 이렇게 , 이렇게 해서, 같은 파일에 수 .
./config/index.ts.
import { ExampleOpts } from '../types'
// Defaults
export const ExampleOptsDefault : ExampleOpts = {
opt1: 'default value 1',
opt2: 'default value 2',
opt3: 'default value 3',
}
은 '다 같이 '의 .
./index.ts.
import { ExampleOpts } from './types'
import { ExampleOptsDefault } from './config'
import merge from 'merge'
// The ? makes the parameter optional
export function test1(options?: ExampleOpts) {
// merge tries to load in the defaults first, then options next if it's defined
const merged_opts: ExampleOpts = merge.recursive(ExampleOptsDefault, options)
// log the result to the console
console.log(merged_opts)
}
또 다른 방법은 Pick 유틸리티 유형을 사용하여 필요한 속성을 선택하는 것입니다.
interface IX {
a: string,
b: any,
c: AnotherType
}
let x: Pick<IX, 'a'> = {
a: 'abc'
}
그런 다음 실제 IX 개체를 선언할 때 다음과 같이 기본값을 새 값과 병합합니다.
const newX: IX = {
...x,
b: 'b',
c: () => {}
}
이 답변은 "How To Up A Type Script Interface Default Value?"에서 가져온 것입니다.
언급URL : https://stackoverflow.com/questions/35074365/typescript-interface-default-values
'source' 카테고리의 다른 글
파워 쿼리를 사용하여 뛰어난 성능을 발휘하는 Json (0) | 2023.03.20 |
---|---|
각진 '='의 의미는 무엇입니까?JS 지시 격리 범위 선언? (0) | 2023.03.20 |
예쁜 영구 링크 목록 및 게시 제목 내보내기 (0) | 2023.03.20 |
ng-repeat 내에서 ng-click에 의해 호출되는 할당식 동작 (0) | 2023.03.20 |
리액트 리덕스 접속 컴포넌트를 유닛 테스트하는 방법 (0) | 2023.03.20 |