답변:
로 표시 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으로이 문제를 접근하는 방법에 대해 다른 관점을 줄 수 있습니다.
LooseObject오류가 발생할 수 있습니다.
아니면 한 번에 :
var obj:any = {}
obj.prop = 5;
any를 사용하기 위해 많은 것들을 캐스팅해야한다면 요점은 무엇입니까 ? 내 코드에서 추가 노이즈가 발생합니다 .. : /
any합니다. TypeScript는 컴파일 타임에 (잠재적) 오류를 포착하는 데 사용됩니다. any오류를 음소거 하려고 캐스팅하면 입력 기능이 손실되고 순수한 JS로 돌아갈 수 있습니다. anyTS 정의를 작성할 수없는 코드를 가져 오거나 JS에서 TS로 코드를 마이그레이션하는 동안 코드를 가져 오는 경우에만 이상적으로 사용해야합니다.
나는 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 = {};
I still have <any>{그런 다음 컴파일하지 않았습니다. 타이프 라이터는 발광에 그것을 제거하는 것
var foo: IFoo = {} as any선호됩니다. 타입 캐스팅을위한 구식 구문은 TSX (Typescript-ified JSX)와 충돌했습니다.
이 솔루션은 객체에 특정 유형이있을 때 유용합니다. 다른 소스에 객체를 가져올 때와 같습니다.
let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.
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 전혀 유형을&의 유형을 선언 할 때 표시됨 objectWithAllProps)을 사용하여 새 유형을 즉석에서 (즉 동적으로) 작성하고 있음을 명확하게 전달합니다.알아야 할 사항
existingObject그대로 유지되므로email 속성 . 대부분의 함수형 프로그래머에게는 그 결과가 좋았습니다. 유일한 새로운 변화).다음과 같은 방법으로 기존 객체에 멤버를 추가 할 수 있습니다
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();
이 작업을 수행 할 수 없으므로
obj.prop = 'value';
TS 컴파일러와 린터가 엄격하지 않으면 다음과 같이 작성할 수 있습니다.
obj['prop'] = 'value';
TS 컴파일러 또는 linter가 엄격한 경우 다른 대답은 typecast입니다.
var obj = {};
obj = obj as unknown as { prop: string };
obj.prop = "value";
'any'로 타입 캐스팅하여 모든 종류의 객체에 새로운 속성을 저장하십시오.
var extend = <any>myObject;
extend.NewProperty = anotherObject;
나중에 확장 객체를 'any'로 다시 캐스팅하여 검색 할 수 있습니다.
var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;
가장 안전한 방법은 안전한 타이핑을 사용하는 것입니다.
interface customObject extends MyObject {
newProp: string;
newProp2: number;
}
다음은 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 어설 션 함수를 사용 합니다 . 의 반환 유형 assign입니다 void달리 Object.assign.
Typescript를 사용하는 경우 아마도 형식 안전성을 사용하려고합니다. 이 경우 Naked Object와 'any'는 반대 표시됩니다.
Object 또는 {}를 사용하지 않는 것이 좋지만 이름이 지정된 유형이 있습니다. 또는 고유 한 필드로 확장해야하는 특정 유형의 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:PropAble = getTheGivenObject();
k.props = "value for props";
완전히 안전한 형식의 유일한 솔루션은 이것 이지만, 조금 말이 많으며 여러 객체를 만들어야합니다.
당신이 경우 해야한다 먼저 빈 객체를 만든 다음 두 가지 솔루션 중 하나를 선택하십시오. 를 사용할 때마다 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;
}