TypeScript에서 일반 JavaScript 개체 유형을 대상으로 하는 방법이 있습니까?
2021년 업데이트
새로운 기능을 사용하는 작업 솔루션은 다음 답변을 참조하십시오. https://stackoverflow.com/a/59647842/1323504
저는 어떤 종류의 평범한 자바스크립트 객체를 반환하는 함수를 쓰려고 합니다.그 물체의 특징은 알려지지 않았고, 현재로서는 흥미롭지 않으며, 단지 그것이 평범한 물체라는 사실뿐입니다.예를 들어 jQuery의 값을 만족시키는 일반 객체를 의미합니다.isPlainObject기능.예를들면
{ a: 1, b: "b" }
일반적인 목적이지만,
var obj = new MyClass();
그것은 "유효한" 객체가 아닙니다.constructor아닙니다ObjectjQuery는 보다 정확한 작업을 수행합니다.$.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 |