TypeScript에서 일반 JavaScript 개체 유형을 대상으로 하는 방법이 있습니까?
2021년 업데이트
새로운 기능을 사용하는 작업 솔루션은 다음 답변을 참조하십시오. https://stackoverflow.com/a/59647842/1323504
저는 어떤 종류의 평범한 자바스크립트 객체를 반환하는 함수를 쓰려고 합니다.그 물체의 특징은 알려지지 않았고, 현재로서는 흥미롭지 않으며, 단지 그것이 평범한 물체라는 사실뿐입니다.예를 들어 jQuery의 값을 만족시키는 일반 객체를 의미합니다.isPlainObject
기능.예를들면
{ a: 1, b: "b" }
일반적인 목적이지만,
var obj = new MyClass();
그것은 "유효한" 객체가 아닙니다.constructor
아닙니다Object
jQuery는 보다 정확한 작업을 수행합니다.$.isPlainObject
하지만 그건 문제의 범위 밖입니다.
사용하려고 하면Object
유형을 입력하면 다음에서 상속되기 때문에 모든 사용자 지정 개체와 호환됩니다.Object
.
TypeScript에서 "일반 객체" 유형을 대상으로 하는 방법이 있습니까?
예를 들어 이것을 만족시킬 수 있는 타입을 원합니다.
var obj: PlainObject = { a: 1 }; // perfect
var obj2: PlainObject = new MyClass(); // compile-error: not a plain object
유스케이스
저는 서버측 방식에 강한 타입의 스텁을 가지고 있습니다.이 스텁은 ASP.NET MVC 컨트롤러를 기반으로 하는 코드 생성기 중 하나에서 생성됩니다.
export class MyController {
...
static GetResult(id: number): JQueryPromise<PlainObject> {
return $.post("mycontroller/getresult", ...);
}
...
}
이제 제가 소비자 계층에서 그것을 부를 때, 저는 이런 것을 할 수 있습니다.
export class MyViewModelClass {
...
LoadResult(id: number): JQueryPromise<MyControllerResult> { // note the MyControllerResult strong typing here
return MyController.GetResult(id).then(plainResult => new MyControllerResult(plainResult));
}
...
}
그리고 이제 컨트롤러 방식이 되돌아온다고 상상해 보십시오.JQueryPromise<any>
또는JQueryPromise<Object>
그리고 이제 내가 우연히 글을 쓴다고 상상해 보세요.done
대신에then
숨겨진 오류가 있습니다. 뷰 모델 메소드가 올바른 약속을 반환하지 않지만 컴파일 오류는 발생하지 않기 때문입니다.
내게 이런 상상이 있다면,PlainObject
유형, 다음과 같은 컴파일 오류가 발생할 것으로 예상됩니다.PlainObject
로 변환할 수 없습니다.MyControllerResult
,아니면 그런 비슷한 것.
TypeScript 3.7.2에서 테스트됨:
플랫 일반 객체의 경우 다음 작업을 수행할 수 있습니다.
type Primitive =
| bigint
| boolean
| null
| number
| string
| symbol
| undefined;
type PlainObject = Record<string, Primitive>;
class MyClass {
//
}
const obj1: PlainObject = { a: 1 }; // Works
const obj2: PlainObject = new MyClass(); // Error
중첩된 일반 객체의 경우:
type Primitive =
| bigint
| boolean
| null
| number
| string
| symbol
| undefined;
type JSONValue = Primitive | JSONObject | JSONArray;
interface JSONObject {
[key: string]: JSONValue;
}
interface JSONArray extends Array<JSONValue> { }
const obj3: JSONObject = { a: 1 }; // Works
const obj4: JSONObject = new MyClass(); // Error
const obj5: JSONObject = { a: { b: 1 } }; // Works
const obj6: JSONObject = { a: { b: { c: 1 } } }; // Works
const obj7: JSONObject = { a: { b: { c: { d: 1 } } } }; // Works
코드는 https://github.com/microsoft/TypeScript/issues/3496#issuecomment-128553540 에서 적용한 것입니다.
프리미티브는 mdn 웹 문서 > 프리미티브를 참조하십시오.
대안적인 해결책은 sindresorhus / type-fest 라이브러리를 사용하거나 https://github.com/sindresorhus/type-fest/blob/main/source/basic.d.ts 에서 제공하는 구현을 사용하는 것입니다.
제 코드에는 당신이 요구하는 것과 유사한 것이 있습니다.
export type PlainObject = { [name: string]: any }
export type PlainObjectOf<T> = { [name: string]: T }
그리고 저는 그것을 위한 타입 가드도 가지고 있습니다.
export function isPlainObject(obj: any): obj is PlainObject {
return obj && obj.constructor === Object || false;
}
편집
네, 찾으시는 물건은 이해합니다만, 아쉽게도 불가능합니다.
내가 당신을 제대로 이해했다면 당신이 원하는 것은 다음과 같습니다.
type PlainObject = {
constructor: ObjectConstructor;
[name: string]: any
}
문제는 'lib.d.ts'에서 Object가 다음과 같이 정의된다는 것입니다.
interface Object {
/** The initial value of Object.prototype.constructor is the standard built-in Object constructor. */
constructor: Function;
...
}
그리고 나서 이것은:
let o: PlainObject = { key: "value" };
오류가 발생하는 결과:
Type '{ key: string; }' is not assignable to type 'PlainObject'.
Types of property 'constructor' are incompatible.
Type 'Function' is not assignable to type 'ObjectConstructor'.
Property 'getPrototypeOf' is missing in type 'Function'.
재귀적 유형(원시 솔루션)을 시도할 수 있습니다.
type SerializableObject = { [x: string]: SerializableObject | number | string | [] };
좋지 않아요, 나쁘지 않아요 :)
TS 4.9에서 사용할 수 있는 기능은 다음과 같습니다.
type PlainObject = Record<string, {}>;
class MyClass {}
function test(one: PlainObject) {}
test({ a: 1, b: "a", c: new MyClass() }); // OK
test(1); // Error
test("a"); // Error
test([1, 2, 3]); // Error
test(new Date()); // Error
test(new Map()); // Error
test(new Set()); // Error
test(new MyClass()); // Error
허용된 답변과의 차이점은 기본값뿐만 아니라 일반 개체에도 복잡한 값이 포함될 수 있다는 것입니다.
type ObjectOfPrimitives = Record<string, Primitive>;
function test(one: ObjectOfPrimitives) {}
test({
a: 1,
b: "a",
c: new MyClass(), // Error: Type 'MyClass' is not assignable to type 'ObjectOfPrimitives'.
});
언급URL : https://stackoverflow.com/questions/42027864/is-there-any-way-to-target-the-plain-javascript-object-type-in-typescript
'programing' 카테고리의 다른 글
SQL Server 기본 문자 인코딩 (0) | 2023.06.25 |
---|---|
R의 data.frame에서 전체 열 제거 (0) | 2023.06.25 |
스프링 부트 응용 프로그램에서 인터셉트의 실행 순서를 정의하는 방법은 무엇입니까? (0) | 2023.06.25 |
얕은 깃 서브모듈을 만드는 방법은? (0) | 2023.06.25 |
PLS-00302가 표시되는 이유: 구성 요소가 있을 때 선언되어야 합니까? (0) | 2023.06.25 |