TypeScript에서 오브젝트에 속성을 동적으로 할당하려면 어떻게 해야 합니까?
Javascript에서 오브젝트에 속성을 프로그램적으로 할당하려면 다음과 같이 합니다.
var obj = {};
obj.prop = "value";
그러나 TypeScript에서는 다음과 같은 오류가 발생합니다.
유형 '{}'의 값에 'prop' 속성이 없습니다.
TypeScript에서 개체에 새 속성을 할당하려면 어떻게 해야 합니까?
인덱스 타입
It is possible to denote 다음을 나타낼 수 있습니다.obj as ~하듯이any, 그러나 그것은 형식적인 목적을 달성한 것입니다.하지만, 그것은 타이프스크립트를 사용하는 전체 목적을 망친다. obj = {} implies 암시하다obj is an 는 입니다.Object. 로 시 .하 marking it as?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;
Record<Keys,Type> 유형
업데이트(2020년 8월):@transang이 댓글로 이 얘기를 꺼냈어요.
Record<Keys,Type>는 타이프 스크립트의 유틸리티 유형입니다.속성 이름을 알 수 없는 키와 값의 쌍에 대해 훨씬 깔끔한 대체 수단입니다.가 있다Record<Keys,Type>입니다.{[k: Keys]: Type}서 ''는Keys★★★★★★★★★★★★★★★★★」Type할 .IMO, IMO.
비교를 위해서
var obj: {[k: string]: any} = {};
된다
var obj: Record<string,any> = {}
MyType Record 할 수 .
interface MyType extends Record<string,any> {
typesafeProp1?: number,
requiredProp1: string,
}
이것이 원래의 질문에 대한 답변이지만, @GreeneCreations의 답변은 문제에 접근하는 방법에 대한 다른 관점을 제공할 수 있습니다.
또는 올인원:
var obj:any = {}
obj.prop = 5;
이 솔루션은 개체에 특정 유형이 있을 때 유용합니다.오브젝트를 다른 소스로 가져올 때처럼요.
let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.
저는 약간...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 = {};
컴파일러는 필요에 따라 출력할 수 있다고 불평합니다.하지만, 이것은 효과가 있습니다.
const s = {};
s['prop'] = true;
JavaScript의 "구성"에 대해 생각할 때 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새로운 타입의 온더플라이(즉, 역동적으로)를 작곡하고 있음을 명확하게 알 수 있습니다.
유의사항
- Object.assign에는 TypeScript를 작성할 때 고려해야 할 고유한 측면이 있습니다(대부분의 경험이 풍부한 JS 개발자에게 잘 알려져 있습니다).
- 은 변하기 의 방법으로 할 수 불변의 ). 즉, '의 방법', '불변의 방법', '불변의 방법', '불변의 방법', '불변의 방법', '불변의 방법', '불변의 방법', '불변의 방법', '불변의 방법', '불변의 방법'입니다.
existingObject손대지 않은 채로 있기 때문에, 그 때문에, 이 기능은 없습니다.email유물. 밖에 없기 입니다.)대부분의 기능성 스타일의 프로그래머에게 이것은 좋은 일입니다.왜냐하면 그 결과는 유일한 새로운 변화이기 때문입니다). - Object.assign은 평면 객체가 있을 때 가장 잘 작동합니다.nullable 속성을 포함하는 두 개의 중첩된 개체를 결합하는 경우 정의되지 않은 상태로 truthy 값을 덮어쓸 수 있습니다.Object.assign 인수의 순서를 주의하면 문제가 없습니다.
- 은 변하기 의 방법으로 할 수 불변의 ). 즉, '의 방법', '불변의 방법', '불변의 방법', '불변의 방법', '불변의 방법', '불변의 방법', '불변의 방법', '불변의 방법', '불변의 방법', '불변의 방법'입니다.
이를 위한 또 하나의 옵션은 컬렉션으로 속성에 액세스하는 것입니다.
var obj = {};
obj['prop'] = "value";
확산 연산자를 사용하여 이전 개체를 기반으로 새 개체를 생성할 수 있습니다.
interface MyObject {
prop1: string;
}
const myObj: MyObject = {
prop1: 'foo',
}
const newObj = {
...myObj,
prop2: 'bar',
}
console.log(newObj.prop2); // 'bar'
TypeScript는 원래 객체의 모든 필드를 추론하고 VSCode는 자동 완성 등을 수행합니다.
다음을 사용할 수 있습니다.
this.model = Object.assign(this.model, { newProp: 0 });
케이스 1:
var car = {type: "BMW", model: "i8", color: "white"};
car['owner'] = "ibrahim"; // You can add a property:
케이스 2:
var car:any = {type: "BMW", model: "i8", color: "white"};
car.owner = "ibrahim"; // You can set a property: use any type
늦었지만 간단한 대답
let prop = 'name';
let value = 'sampath';
this.obj = {
...this.obj,
[prop]: value
};
가장 심플한 것은 다음과 같습니다.
const obj = <any>{};
obj.prop1 = "value";
obj.prop2 = "another value"
.Object.assign는 속성을 변경할 때마다 변수 유형을 자동으로 조정합니다.추가 변수, 유형 어설션, 명시적 유형 또는 개체 복사본이 필요하지 않습니다.
function assign<T, U>(target: T, source: U): asserts target is T & U {
Object.assign(target, source)
}
const obj = {};
assign(obj, { prop1: "foo" })
// const obj now has type { prop1: string; }
obj.prop1 // string
assign(obj, { prop2: 42 })
// const obj now has type { prop1: string; prop2: number; }
obj.prop2 // number
// const obj: { prop1: "foo", prop2: 42 }
참고: 샘플은 TS 3.7 어설션 기능을 사용합니다.반환 유형:assignvoid는, 「」와 달리, 「」는 다릅니다.Object.assign.
이렇게 할 수 없기 때문에:
obj.prop = 'value';
TS 컴파일러와 린터가 엄격하지 않은 경우 다음과 같이 기술할 수 있습니다.
obj['prop'] = 'value';
TS 컴파일러 또는 린터가 엄격한 경우, 또 다른 답은 타이프캐스트입니다.
var obj = {};
obj = obj as unknown as { prop: string };
obj.prop = "value";
이 「」라고 합니다.Object(즉, 키와 값의 쌍), 사용:
const obj: {[x: string]: any} = {}
obj.prop = 'cool beans'
기존 오브젝트에 멤버를 추가할 수 있습니다.
- 유형 확대(읽기: 인터페이스 확장/특화)
- 원물을 확장 활자로 주조하다
- 오브젝트에 멤버를 추가하다
interface IEnhancedPromise<T> extends Promise<T> {
sayHello(): void;
}
const p = Promise.resolve("Peter");
const enhancedPromise = p as IEnhancedPromise<string>;
enhancedPromise.sayHello = () => enhancedPromise.then(value => console.info("Hello " + value));
// eventually prints "Hello Peter"
enhancedPromise.sayHello();
안전한 타이핑을 사용하는 것이 가장 좋습니다.권장할 수 있는 방법은 다음과 같습니다.
interface customObject extends MyObject {
newProp: string;
newProp2: number;
}
Angular에 대한 @jmvtrinidad 솔루션 확장,
이미 입력된 개체로 작업할 때 새 속성을 추가하는 방법은 다음과 같습니다.
let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.
" " " 를 사용하고 otherProperty
<div *ngIf="$any(user).otherProperty">
...
...
</div>
앵귤러 $any()의 캐스팅으로서anyTypeScript와 동일하게 입력합니다.<any>또는as anycast 가 사용됩니다.
새 속성을 'any'로 입력하여 모든 종류의 개체에 저장합니다.
var extend = <any>myObject;
extend.NewProperty = anotherObject;
나중에 확장 개체를 다시 '임의'로 캐스팅하여 가져올 수 있습니다.
var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;
이전 유형을 보존하려면 개체를 임시로 임의의 위치에 캐스팅하십시오.
var obj = {}
(<any>obj).prop = 5;
새 동적 속성은 캐스트를 사용하는 경우에만 사용할 수 있습니다.
var a = obj.prop; ==> Will generate a compiler error
var b = (<any>obj).prop; ==> Will assign 5 to b with no error;
TypeScript에서 개체에 동적으로 속성을 할당합니다.
그러기 위해서는 다음과 같은 타입 스크립트인터페이스를 사용할 필요가 있습니다.
interface IValue {
prop1: string;
prop2: string;
}
interface IType {
[code: string]: IValue;
}
그렇게 쓸 수 있다
var obj: IType = {};
obj['code1'] = {
prop1: 'prop 1 value',
prop2: 'prop 2 value'
};
완전 타입 세이프한 솔루션은 이것뿐입니다만, 약간 말이 많아 여러 개체를 작성해야 합니다.
먼저 빈 개체를 만들어야 하는 경우 다음 두 가지 솔루션 중 하나를 선택하십시오.사용할 때마다as안전을 잃고 있어요
안전한 솔루션
의 종류object안은 안전합니다.getObject즉,object.a종류일 것이다string | undefined
interface Example {
a: string;
b: number;
}
function getObject() {
const object: Partial<Example> = {};
object.a = 'one';
object.b = 1;
return object as Example;
}
쇼트 솔루션
의 object안은 안전하지 않다getObject즉,object.a이 될 것이다string그 임무가 수행되기도 전에.
interface Example {
a: string;
b: number;
}
function getObject() {
const object = {} as Example;
object.a = 'one';
object.b = 1;
return object;
}
할 수 (는 지금 을 타이프스크립트 버전으로 사용하고 .)"typescript": "~4.5.5")
let contextItem = {} as any;
이제 모든 속성을 추가하고 어디서나 사용할 수 있습니다.맘에 들다
contextItem.studentName = "kushal";
나중에 다음과 같이 사용할 수 있습니다.
console.log(contextItem.studentName);
나는 바로 이 주제에 대해 기사를 썼다.
Typescript – 실행 시 개체와 해당 유형을 확장합니다.
https://tech.xriba.io/2022/03/24/typescript-enhance-an-object-and-its-type-at-runtime/
다음과 같은 Typescript 개념에서 영감을 얻을 수 있습니다.
Typescript를 사용하는 경우 type safety를 사용해야 합니다.이 경우 naked Object와 'any'가 반대됩니다.
개체 또는 {}은(는) 사용하지 않고 일부 명명된 유형을 사용하는 것이 좋습니다. 또는 고유한 필드로 확장해야 하는 특정 유형의 API를 사용하고 있을 수 있습니다.이게 효과가 있다는 걸 알아냈어.
class Given { ... } // API specified fields; or maybe it's just Object {}
interface PropAble extends Given {
props?: string; // you can cast any Given to this and set .props
// '?' indicates that the field is optional
}
let g:Given = getTheGivenObject();
(g as PropAble).props = "value for my new field";
// to avoid constantly casting:
let k = getTheGivenObject() as PropAble;
k.props = "value for props";
이 선언을 추가하여 경고를 무음화할 수 있습니다.
declare var obj: any;
상태 저장소로 기능하는 개체의 일부를 업데이트하려고 할 때 이 문제가 발생했습니다.
type State = {
foo: string;
bar: string;
baz: string;
};
const newState = { foo: 'abc' };
if (someCondition) {
newState.bar = 'xyz'
}
setState(newState);
시나리오에서는 「」를 사용하는 솔루션이 됩니다.Partial<T>. 를?토큰. 토큰에 대한 자세한 내용은 유형의 모든 속성을 옵션으로 설정하는 방법에 대한 자세한 SO 항목을 참조하십시오.
가 해결했습니다.Partial<T>:
type State = {
foo: string;
bar: string;
baz: string;
};
const newState: Partial<State> = { foo: 'abc' };
if (someCondition) {
newState.bar = 'xyz';
}
setState(newState);
이는 프레간테가 답변에서 설명한 것과 유사하지만, 이 특정 사용 사례(프런트 엔드 애플리케이션에서 흔히 볼 수 있는)에 대해 좀 더 명확한 그림을 그리고 싶었습니다.
ES6 사용Map이 고정 수 있는 , 그의 임의의 은 임의의 것으로 합니다.
이게 제가 지향할 가이드라인인 것 같아요.ES6 맵은 "Typescript(타입스크립트)"의 ES6 맵에 기재된 바와 같이 타이프스크립트로 작성할 수 있습니다.
옵션 속성의 주요 사용 사례는 기능의 "옵션" 매개 변수입니다.이름 있는 파라미터 JavaScript 사용(typescript에 기반) 이 경우 허용되는 속성의 정확한 목록을 미리 알 수 있습니다.따라서 가장 현명한 방법은 명시적인 인터페이스를 정의하고 임의로 사용할 수 있는 모든 것을 만드는 것입니다.?https://stackoverflow.com/a/18444150/895245 에서 가능한 한 많은 타입 체크를 받을 수 있습니다.
const assert = require('assert')
interface myfuncOpts {
myInt: number,
myString?: string,
}
function myfunc({
myInt,
myString,
}: myfuncOpts) {
return `${myInt} ${myString}`
}
const opts: myfuncOpts = { myInt: 1 }
if (process.argv.length > 2) {
opts.myString = 'abc'
}
assert.strictEqual(
myfunc(opts),
'1 abc'
)
그리고 Map이 정말로 임의적이고(무한히 많은 가능한 키) 고정된 유형인 경우 다음과 같이 Map을 사용합니다.
const assert = require('assert')
const integerNames = new Map<number, string>([[1, 'one']])
integerNames.set(2, 'two')
assert.strictEqual(integerNames.get(1), 'one')
assert.strictEqual(integerNames.get(2), 'two')
테스트 대상:
"dependencies": {
"@types/node": "^16.11.13",
"typescript": "^4.5.4"
}
이것을 시험해 보세요.
export interface QueryParams {
page?: number,
limit?: number,
name?: string,
sort?: string,
direction?: string
}
그럼 쓰세요
const query = {
name: 'abc'
}
query.page = 1
언급URL : https://stackoverflow.com/questions/12710905/how-do-i-dynamically-assign-properties-to-an-object-in-typescript
'codememo' 카테고리의 다른 글
| Angular의 상위 컨트롤러에서 디렉티브의 메서드를 호출합니다.JS (0) | 2023.03.14 |
|---|---|
| Angular의 UI 라우터에 URL이 없는 상태의 파라미터JS (0) | 2023.03.14 |
| Woocommerce - 플러그인에서 제품 유형을 확인하는 방법 (0) | 2023.03.14 |
| @트랜잭션 주석은 saveAndFlush에서 작동합니까? (0) | 2023.03.14 |
| Oracle에 타임스탬프를 삽입하는 방법 (0) | 2023.03.14 |