[typescript] TypeScript에서 객체에 속성을 동적으로 할당하려면 어떻게합니까?

프로그래밍 방식으로 Javascript의 객체에 속성을 할당하려면 다음과 같이하십시오.

var obj = {};
obj.prop = "value";

그러나 TypeScript에서는 다음과 같은 오류가 발생합니다.

‘prop’특성이 ‘{}’유형의 값에 존재하지 않습니다.

TypeScript에서 객체에 새로운 속성을 할당하려면 어떻게해야합니까?



답변

로 표시 obj하는 것이 가능 any하지만 타입 스크립트 사용의 전체 목적을 상실합니다. obj = {}암시 obj입니다 Object. any의미가없는 것으로 표시하십시오 . 원하는 일관성을 달성하기 위해 인터페이스를 다음과 같이 정의 할 수 있습니다.

interface LooseObject {
    [key: string]: any
}

var obj: LooseObject = {};

또는 컴팩트하게 만들기 :

var obj: {[k: string]: any} = {};

LooseObject모든 문자열이있는 필드를 키로, any유형을 값으로 사용할 수 있습니다.

obj.prop = "value";
obj.prop2 = 88;

이 솔루션의 진정한 우아함은 인터페이스에 typesafe 필드를 포함 할 수 있다는 것입니다.

interface MyType {
    typesafeProp1?: number,
    requiredProp1: string,
    [key: string]: any
}

var obj: MyType ;
obj = { requiredProp1: "foo"}; // valid
obj = {} // error. 'requiredProp1' is missing
obj.typesafeProp1 = "bar" // error. typesafeProp1 should be a number

obj.prop = "value";
obj.prop2 = 88;

이것은 원래의 질문에 대답하면서, 대답 여기 @GreeneCreations으로이 문제를 접근하는 방법에 대해 다른 관점을 줄 수 있습니다.


답변

아니면 한 번에 :

  var obj:any = {}
  obj.prop = 5;


답변

나는 any다른면 에 넣는 경향이 있습니다. 즉 var foo:IFoo = <any>{};이와 같은 것은 여전히 ​​유형 안전합니다.

interface IFoo{
    bar:string;
    baz:string;
    boo:string;
}

// How I tend to intialize 
var foo:IFoo = <any>{};

foo.bar = "asdf";
foo.baz = "boo";
foo.boo = "boo";

// the following is an error, 
// so you haven't lost type safety
foo.bar = 123; 

또는 이러한 특성을 선택 사항으로 표시 할 수 있습니다.

interface IFoo{
    bar?:string;
    baz?:string;
    boo?:string;
}

// Now your simple initialization works
var foo:IFoo = {};

온라인으로 사용해보십시오


답변

이 솔루션은 객체에 특정 유형이있을 때 유용합니다. 다른 소스에 객체를 가져올 때와 같습니다.

let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.


답변

컴파일러는 불평하지만 여전히 원하는대로 출력해야한다고 불평합니다. 그러나 이것은 효과가 있습니다.

var s = {};
s['prop'] = true;


답변

그에 대한 또 다른 옵션은 컬렉션으로 속성에 액세스하는 것입니다.

var obj = {};
obj['prop'] = "value";


답변

JavaScript의 “composition”에 대해 생각할 때마다 사용하는 기술이기 때문에 Object.assign을 참조하는 답변이 없다는 것에 놀랐습니다.

그리고 TypeScript에서 예상대로 작동합니다.

interface IExisting {
    userName: string
}

interface INewStuff {
    email: string
}

const existingObject: IExisting = {
    userName: "jsmith"
}

const objectWithAllProps: IExisting & INewStuff = Object.assign({}, existingObject, {
    email: "jsmith@someplace.com"
})

console.log(objectWithAllProps.email); // jsmith@someplace.com

장점

  • 사용할 필요가 없으므로 any 전혀 유형을
  • TypeScript의 집계 유형 ( &의 유형을 선언 할 때 표시됨 objectWithAllProps)을 사용하여 새 유형을 즉석에서 (즉 동적으로) 작성하고 있음을 명확하게 전달합니다.

알아야 할 사항

  1. Object.assign은 TypeScript를 작성할 때 고려해야 할 고유 한 측면 (가장 경험이 많은 JS 개발자에게 잘 알려진)을 가지고 있습니다.
    • 그것은 변경 가능한 방식으로 또는 불변의 방식으로 사용될 수 있습니다 (위의 불변의 방법을 보여줍니다. 즉, existingObject그대로 유지되므로email 속성 . 대부분의 함수형 프로그래머에게는 그 결과가 좋았습니다. 유일한 새로운 변화).
    • 더 평평한 객체가있을 때 Object.assign이 가장 효과적입니다. 널 입력 가능 특성을 포함하는 두 개의 중첩 된 오브젝트를 결합하는 경우, 정의되지 않은 값으로 정의 된 값을 겹쳐 쓸 수 있습니다. Object.assign 인수의 순서를 조심하면 괜찮을 것입니다.