Typescript d.ts 파일에 정의된 인터페이스 속성 유형을 재정의하고 있습니다.
되어 있는 ?*.d.ts★★★★★★★★★★★★★★★★★★?
예를 들어 다음과 같습니다.의 x.d.ts되어 있습니다.
interface A {
property: number;
}
내가 쓰는 타이프스크립트 파일에서 변경하고 싶다.
interface A {
property: Object;
}
이마저도 효과가 있을 것이다.
interface B extends A {
property: Object;
}
이 접근방식이 효과가 있을까요?시스템을 사용해보니 작동이 되지 않았다.그게 가능한지 확인하고 싶으신 건가요?
먼저 필드를 필터링한 후 결합하는 방법을 사용합니다.
참조 형식에서 속성 제외
interface A {
x: string
}
export type B = Omit<A, 'x'> & { x: number };
인터페이스:
interface A {
x: string
}
interface B extends Omit<A, 'x'> {
x: number
}
type ModifiedType = Modify<OriginalType, {
a: number;
b: number;
}>
interface ModifiedInterface extends Modify<OriginalType, {
a: number;
b: number;
}> {}
ZSKYcat에서 영감을 얻어 extends Omit츠키다
type Modify<T, R> = Omit<T, keyof R> & R; // before typescript@3.5 type Modify<T, R> = Pick<T, Exclude<keyof T, keyof R>> & R
예:
interface OriginalInterface {
a: string;
b: boolean;
c: number;
}
type ModifiedType = Modify<OriginalInterface , {
a: number;
b: number;
}>
// ModifiedType = { a: number; b: number; c: number; }
단계별 진행:
type R0 = Omit<OriginalType, 'a' | 'b'> // { c: number; }
type R1 = R0 & {a: number, b: number } // { a: number; b: number; c: number; }
type T0 = Exclude<'a' | 'b' | 'c' , 'a' | 'b'> // 'c'
type T1 = Pick<OriginalType, T0> // { c: number; }
type T2 = T1 & {a: number, b: number } // { a: number; b: number; c: number; }
v2.0 상세 변경
interface Original {
a: {
b: string
d: {
e: string // <- will be changed
}
}
f: number
}
interface Overrides {
a: {
d: {
e: number
f: number // <- new key
}
}
b: { // <- new key
c: number
}
}
type ModifiedType = ModifyDeep<Original, Overrides>
interface ModifiedInterface extends ModifyDeep<Original, Overrides> {}
// ModifiedType =
{
a: {
b: string
d: {
e: number
f: number
}
}
b: {
c: number
}
f: number
}
★★ModifyDeep 이하에 나타냅니다.
기존 속성의 유형은 변경할 수 없습니다.
속성을 추가할 수 있습니다.
interface A {
newProperty: any;
}
그러나 기존 유형의 변경:
interface A {
property: any;
}
에러가 발생합니다.
후속 변수 선언의 유형은 같아야 합니다.변수 'property'는 'number' 유형이어야 하지만 여기에는 'any' 유형이 있습니다.
물론 기존 인터페이스를 확장하는 자체 인터페이스를 가질 수 있습니다.이 경우 유형을 호환되는 유형으로만 재정의할 수 있습니다. 예를 들어 다음과 같습니다.
interface A {
x: string | number;
}
interface B extends A {
x: number;
}
아마 ' 쪽인가', '어느 쪽인가', '어느 쪽인가'는 하지 않는 것이 것 .Object대신 「」를 해 주세요.any.
유형의 문서에는 다음과 같이 기술되어 있습니다.
any type은 기존 JavaScript를 사용하는 강력한 방법이며 컴파일 중에 타입 체크를 단계적으로 선택 또는 해제할 수 있습니다.오브젝트도 다른 언어에서와 마찬가지로 비슷한 역할을 할 것으로 예상할 수 있습니다.그러나 Object 유형의 변수에서는 값만 할당할 수 있습니다. 실제로 존재하는 변수라도 임의 메서드를 호출할 수 없습니다.
let notSure: any = 4;
notSure.ifItExists(); // okay, ifItExists might exist at runtime
notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)
let prettySure: Object = 4;
prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.
나 같은 게으른 사람들을 위한 짧은 대답:
type Overrided = Omit<YourInterface, 'overrideField'> & { overrideField: <type> };
interface Overrided extends Omit<YourInterface, 'overrideField'> {
overrideField: <type>
}
@zSkycat의 답변을 조금 확장하면 두 가지 오브젝트 유형을 받아들이고 두 번째 오브젝트의 멤버가 첫 번째 멤버를 덮어쓰고 병합된 유형을 반환하는 범용을 만들 수 있습니다.
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
type Merge<M, N> = Omit<M, Extract<keyof M, keyof N>> & N;
interface A {
name: string;
color?: string;
}
// redefine name to be string | number
type B = Merge<A, {
name: string | number;
favorite?: boolean;
}>;
let one: A = {
name: 'asdf',
color: 'blue'
};
// A can become B because the types are all compatible
let two: B = one;
let three: B = {
name: 1
};
three.name = 'Bee';
three.favorite = true;
three.color = 'green';
// B cannot become A because the type of name (string | number) isn't compatible
// with A even though the value is a string
// Error: Type {...} is not assignable to type A
let four: A = three;
Omit"CHANGE: "CHANGE:
interface A {
a: number;
b: number;
}
interface B extends Omit<A, 'a'> {
a: boolean;
}
네스트된 인터페이스를 간단하게 덮어쓸 수 있는 타입을 작성했습니다.
type ModifyDeep<A extends AnyObject, B extends DeepPartialAny<A>> = {
[K in keyof A]: B[K] extends never
? A[K]
: B[K] extends AnyObject
? ModifyDeep<A[K], B[K]>
: B[K]
} & (A extends AnyObject ? Omit<B, keyof A> : A)
/** Makes each property optional and turns each leaf property into any, allowing for type overrides by narrowing any. */
type DeepPartialAny<T> = {
[P in keyof T]?: T[P] extends AnyObject ? DeepPartialAny<T[P]> : any
}
type AnyObject = Record<string, any>
그런 다음 다음과 같이 사용할 수 있습니다.
interface Original {
a: {
b: string
d: {
e: string // <- will be changed
}
}
f: number
}
interface Overrides {
a: {
d: {
e: number
f: number // <- new key
}
}
b: { // <- new key
c: number
}
}
type ModifiedType = ModifyDeep<Original, Overrides>
interface ModifiedInterface extends ModifyDeep<Original, Overrides> {}
// ModifiedType =
{
a: {
b: string
d: {
e: number
f: number
}
}
b: {
c: number
}
f: number
}
, 간단히 , , , , , , , , , , ,.extendNitzan의 답변처럼 완벽하게 작동합니다.
interface A {
x: string | number;
}
interface B extends A {
x: number;
}
확대하거나 일반적으로 유형을 재정의하기 위해 Zskycat의 솔루션을 수행할 수 있습니다.
interface A {
x: string
}
export type B = Omit<A, 'x'> & { x: number };
가 " "일 "A.A의 시)Omit.
예.
interface A extends Record<string | number, number | string | boolean> {
x: string;
y: boolean;
}
export type B = Omit<A, 'x'> & { x: number };
let b: B = { x: 2, y: "hi" }; // no error on b.y!
이,입니다.Omit으로만 Exclude<keyof A, 'x'>인 키가 키string | number저희 같은 경우에는요.so,는,B될 것이다{x: number; }다음 유형의 추가 자산을 받아들입니다.number | string | boolean.
는 다른 을 .OverrideProps유틸리티 타입은 다음과 같습니다.
type OverrideProps<M, N> = { [P in keyof M]: P extends keyof N ? N[P] : M[P] };
예:
type OverrideProps<M, N> = { [P in keyof M]: P extends keyof N ? N[P] : M[P] };
interface A extends Record<string | number, number | string | boolean> {
x: string;
y: boolean;
}
export type B = OverrideProps<A, { x: number }>;
let b: B = { x: 2, y: "hi" }; // error: b.y should be boolean!
내가 같은 사건을 해결할 가능성을 조사하는데 하루를 보낸다는 게 재밌다.이 방법으로는 할 수 없다는 것을 알았습니다.
// a.ts - module
export interface A {
x: string | any;
}
// b.ts - module
import {A} from './a';
type SomeOtherType = {
coolStuff: number
}
interface B extends A {
x: SomeOtherType;
}
원인 A 모듈이 응용 프로그램에서 사용 가능한 모든 유형을 인식하지 못할 수 있습니다.모든 곳에서 온 모든 것을 포팅하고 코드를 이렇게 하는 것은 꽤 지루합니다.
export interface A {
x: A | B | C | D ... Million Types Later
}
자동 완성이 제대로 작동하려면 나중에 유형을 정의해야 합니다.
약간의 속임수를 쓸 수 있습니다.
// a.ts - module
export interface A {
x: string;
}
재정의가 필요하지 않은 경우 자동 완료를 허용하는 일부 유형을 기본적으로 그대로 둡니다.
그리고나서
// b.ts - module
import {A} from './a';
type SomeOtherType = {
coolStuff: number
}
// @ts-ignore
interface B extends A {
x: SomeOtherType;
}
서 '인 예외'를 무효로 합니다.@ts-ignore은 모든 이 예상대로.그리고 재밌는 건 모든 게 예상대로 되는 거야
x코드를 좀 더 엄격하게 할 수 있게 해주십시오., 속성 같은 수 .
2020년 3월 4.1) 버전이 지원한다고 합니다.interfaced.tsfilename을 클릭합니다.
// in test.d.ts
interface A {
a: string
}
export interface B extends A {
a: number
}
// in any ts file
import { B } from 'test.d.ts'
// this will work
const test: B = { a: 3 }
// this will not work
const test1: B = { a: "3" }
이것을 실시하기 위해서 범용 유틸리티 타입이 필요한 경우는, 다음의 솔루션을 생각해 냈습니다.
/**
* Returns object T, but with T[K] overridden to type U.
* @example
* type MyObject = { a: number, b: string }
* OverrideProperty<MyObject, "a", string> // returns { a: string, b: string }
*/
export type OverrideProperty<T, K extends keyof T, U> = Omit<T, K> & { [P in keyof Pick<T, K>]: U };
이게 필요했어요 제 경우엔, 덮어쓸 수 있는 열쇠가 범용 그 자체였기 때문이죠
★★★가Omit준비는 유형에서 속성 제외를 참조하십시오.
기존 속성의 유형만 변경하고 삭제하지 않는 경우 &로 충분합니다.
// Style that accepts both number and percent(string)
type BoxStyle = {
height?: string | number,
width?: string | number,
padding?: string | number,
borderRadius?: string | number,
}
// These are both valid
const box1: BoxStyle = {height: '20%', width: '20%', padding: 0, borderRadius: 5}
const box2: BoxStyle = {height: 85, width: 85, padding: 0, borderRadius: 5}
// Override height and width to be only numbers
type BoxStyleNumeric = BoxStyle & {
height?: number,
width?: number,
}
// This is still valid
const box3: BoxStyleNumeric = {height: 85, width: 85, padding: 0, borderRadius: 5}
// This is not valid anymore
const box4: BoxStyleNumeric = {height: '20%', width: '20%', padding: 0, borderRadius: 5}
Qwerty의 Modify 유틸리티 유형 솔루션을 확장하여 키를 제한합니다.R T를 추가합니다.
export type Modify<T, R extends Partial<Record<keyof T, any>>> = Omit<T, keyof R> & R;
메모: 이 답변에서 사용하고 있는 구문이 이전 답변이 작성되었을 때 사용 가능했는지는 모르겠지만, 이 질문에서 언급한 예를 해결하는 방법은 이 방법이 더 낫다고 생각합니다.
이 항목(인터페이스 속성 덮어쓰기)과 관련된 몇 가지 문제가 있었습니다.이 문제는 다음과 같습니다.
- 먼저 사용할 수 있는 유형의 범용 인터페이스를 만듭니다.
또한, 선택 가능.default에서 볼 수 있듯이 범용 파라미터의 값<T extends number | SOME_OBJECT = number>
type SOME_OBJECT = { foo: "bar" }
interface INTERFACE_A <T extends number | SOME_OBJECT = number> {
property: T;
}
- 그런 다음 일반 매개 변수에 값을 전달(또는 생략하고 기본값 사용)하여 해당 계약에 따라 새 유형을 생성할 수 있습니다.
type A_NUMBER = INTERFACE_A; // USES THE default = number TYPE. SAME AS INTERFACE_A<number>
type A_SOME_OBJECT = INTERFACE_A<SOME_OBJECT> // MAKES { property: SOME_OBJECT }
결과는 다음과 같습니다.
const aNumber: A_NUMBER = {
property: 111 // THIS EXPECTS A NUMBER
}
const anObject: A_SOME_OBJECT = {
property: { // THIS EXPECTS SOME_OBJECT
foo: "bar"
}
}
언급URL : https://stackoverflow.com/questions/41285211/overriding-interface-property-type-defined-in-typescript-d-ts-file
'source' 카테고리의 다른 글
| SQL Chemy: 실제 쿼리 인쇄 (0) | 2022.12.21 |
|---|---|
| MySQL에서 외부 키 제약을 일시적으로 해제하려면 어떻게 해야 합니까? (0) | 2022.12.21 |
| PHP의 GDlib imagecopyresampled 사용 시 PNG 이미지 투명도를 유지할 수 있습니까? (0) | 2022.12.21 |
| 열이 많은 레코드를 MariaDB Columnstore 테이블에 삽입하는 데 시간이 오래 걸립니다. (0) | 2022.12.21 |
| SSH 터널을 통한 MySQL 연결 - 다른 MySQL 서버를 지정하는 방법 (0) | 2022.12.21 |