javascript 객체를 인터페이스의 속성만 포함하도록 줄이는 방법
typescript 를 사용하는 경우 선언된 인터페이스는 다음과 같습니다.
interface MyInterface {
test: string;
}
추가 속성이 있는 구현은 다음과 같습니다.
class MyTest implements MyInterface {
test: string;
newTest: string;
}
예(여기서 변수 'reduced'는 여전히 'new' 속성을 포함합니다).테스트':
var test: MyTest = {test: "hello", newTest: "world"}
var reduced: MyInterface = test; // something clever is needed
질문.
일반적인 방법으로, '축소' 변수를 'MyInterface' 인터페이스에서 선언된 속성만 포함하도록 하려면 어떻게 해야 합니까?
왜죠
이 문제는 각도가 있는 '축소' 변수를 사용하려고 할 때 발생합니다.rest 서비스로 전송하기 전에 toJson - toJson 메서드는 newTest 변수를 변환합니다(컴파일 중에 인스턴스에서 액세스할 수 없는 경우에도). 그러면 나머지 서비스에서는 json에 존재하지 않아야 하는 속성이 있기 때문에 json을 받아들이지 않습니다.
이것을 하는 것은 불가능하다.그 이유는interfaceTypescript 구성이며 변환된 JS 코드가 비어 있습니다.
//this code transpiles to empty!
interface MyInterface {
test: string;
}
따라서 런타임에는 '작업'할 것이 없습니다. 즉, 조회할 속성이 없습니다.
@jamesmoey의 답변은 원하는 결과를 얻기 위한 회피책을 설명합니다.제가 사용하는 유사한 솔루션은 단순히 '인터페이스'를 클래스로 정의하는 것입니다.
class MyInterface {
test: string = undefined;
}
그럼, 을 사용할 수 있습니다.lodash오브젝트에 삽입할 속성을 'interface'에서 선택합니다.
import _ from 'lodash'; //npm i lodash
const before = { test: "hello", newTest: "world"};
let reduced = new MyInterface();
_.assign(reduced , _.pick(before, _.keys(reduced)));
console.log('reduced', reduced)//contains only 'test' property
'JSFiddle' 참조
이것은 실제로 인터페이스인지 명명 규칙인지에 대한 의미론에 얽매이지 않고 나에게 도움이 되는 실용적인 솔루션입니다(예:IMyInterface또는MyInterface)를 사용하여 모의 및 유닛 테스트를 수행할 수 있습니다.
TS 2.1에는 Object Spread 및 Rest가 있으므로 다음과 같은 작업이 가능합니다.
var my: MyTest = {test: "hello", newTest: "world"}
var { test, ...reduced } = my;
축소된 후에는 "test"를 제외한 모든 속성이 포함됩니다.
또 다른 방법:
다른 답변에서도 언급했듯이 실행 시 뭔가를 하지 않을 수 없습니다.TypeScript는 주로 인터페이스/타입 정의, 주석 및 어설션을 제거함으로써 JavaScript로 컴파일합니다.유형 시스템이 지워지고,MyInterface를 필요로 하는 런타임 코드에서는 찾을 수 없습니다.
따라서 축소된 객체에 보관할 키 배열과 같은 것이 필요합니다.
const myTestKeys = ["test"] as const;
그 자체로는 깨지기 쉬워요.MyInterface코드가 변경되어 있는 것을 알 수 없습니다.코드 알림을 만드는 방법 중 하나는 컴파일러 오류를 일으키는 에일리어스 유형의 정의를 설정하는 것입니다.myTestKeys 않다keyof MyInterface:
// the following line will error if myTestKeys has entries not in keyof MyInterface:
type ExtraTestKeysWarning<T extends never =
Exclude<typeof myTestKeys[number], keyof MyInterface>> = void;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Type 'UNION_OF_EXTRA_KEY_NAMES_HERE' does not satisfy the constraint 'never'
// the following line will error if myTestKeys is missing entries from keyof MyInterface:
type MissingTestKeysWarning<T extends never =
Exclude<keyof MyInterface, typeof myTestKeys[number]>> = void;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Type 'UNION_OF_MISSING_KEY_NAMES_HERE' does not satisfy the constraint 'never'
는 않지만,.MyInterface의 행 중 두 가 ""를 수정할 수 충분히 이 있는 를 나타냅니다.myTestKeys.
이것을 보다 일반적이거나 덜 거슬리게 하는 방법이 있지만, TypeScript에서 기대할 수 있는 최선의 방법은 인터페이스가 예기치 않게 변경되었을 때 코드가 컴파일러 경고를 보내는 것입니다.실제로 코드가 실행 시 다른 작업을 수행하는 것은 아닙니다.
마음에 '키'를 .pick()'CHANGE: 'CHANGE: 'CHANGE: 'CHANGE: 'CHANGE:
function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> {
return keys.reduce((o, k) => (o[k] = obj[k], o), {} as Pick<T, K>);
}
의 리리 your your your your your에 사용할 수 .test을 반대하다reduced:
var test: MyTest = { test: "hello", newTest: "world" }
const reduced: MyInterface = pick(test, ...myTestKeys);
console.log(JSON.stringify(reduced)); // {"test": "hello"}
됐다!
인터페이스에만 나열된 속성만 설정/할당하려고 합니까?이러한 기능은 TypeScript에서는 사용할 수 없지만 원하는 동작을 수행하기 위한 함수를 작성하는 것은 매우 간단합니다.
interface IPerson {
name: string;
}
class Person implements IPerson {
name: string = '';
}
class Staff implements IPerson {
name: string = '';
position: string = '';
}
var jimStaff: Staff = {
name: 'Jim',
position: 'Programmer'
};
var jim: Person = new Person();
limitedAssign(jimStaff, jim);
console.log(jim);
function limitedAssign<T,S>(source: T, destination: S): void {
for (var prop in destination) {
if (source[prop] && destination.hasOwnProperty(prop)) {
destination[prop] = source[prop];
}
}
}
예제 newTest 속성에서는 축소된 변수를 통해 액세스할 수 없으므로 유형을 사용하는 것이 목표입니다.타이프 스크립트는 타입 체크를 가져오지만 오브젝트 속성은 조작하지 않습니다.
일반적인 방법으로, '축소' 변수를 'MyInterface' 인터페이스에서 선언된 속성만 포함하도록 하려면 어떻게 해야 합니까?
TypeScript는 구조적이므로 관련 정보를 포함하는 모든 것이 Type Compatible이므로 할당이 가능합니다.
즉, TypeScript 1.6은 라는 개념을 갖게 됩니다.이렇게 하면 오타를 쉽게 잡을 수 있습니다(신선도는 객체 리터럴에만 적용됩니다).
// ERROR : `newText` does not exist on `MyInterface`
var reduced: MyInterface = {test: "hello", newTest: "world"};
간단한 예:
let all_animals = { cat: 'bob', dog: 'puka', fish: 'blup' };
const { cat, ...another_animals } = all_animals;
console.log(cat); // bob
한 가지 해결방법은 다음과 같은 것을 사용할 수 있습니다.class interface and용사다 a a a를 사용합니다.factory method(그 유형의 새 개체를 반환하는 퍼블릭 스태틱 멤버 함수).모델은 허용된 속성을 알 수 있는 유일한 장소이며 모델 변경 시 실수로 업데이트되는 것을 잊지 않습니다.
class MyClass {
test: string;
public static from(myClass: MyClass): MyClass {
return {test: myClass.test};
}
}
예:
class MyTest extends MyClass {
test: string;
newTest: string;
}
const myTest: MyTest = {test: 'foo', newTest: 'bar'};
const myClass: MyClass = MyClass.from(myTest);
언급URL : https://stackoverflow.com/questions/31829951/how-to-reduce-javascript-object-to-only-contain-properties-from-interface
'programing' 카테고리의 다른 글
| Spring-Boot에서 서버에서 다른 rest api 호출 (0) | 2023.03.25 |
|---|---|
| BSON은 무엇이고 JSON과 정확히 어떤 차이가 있나요? (0) | 2023.03.25 |
| mysqli 결과를 JSON으로 변환하는 방법 (0) | 2023.03.25 |
| 오류 TS1192: 모듈 'A.module'에 기본 내보내기가 없습니다. (0) | 2023.03.25 |
| @RunWith를 사용할 때와 @ExtendWith를 사용할 때 (0) | 2023.03.25 |