जब आप शीर्षक देखते हैं तो आप तुरंत "इंटरफ़ेस ए विस्तारित बी {...}" का उत्तर दे सकते हैं, लेकिन यह वह नहीं है जो मैं चाहता हूं।

मेरा मतलब है, मेरे पास दो प्रकार हैं (जैसे ए और बी), और मैं एक प्रकार सी प्राप्त करना चाहता हूं, जिसमें ए के सभी सदस्य और बी के सदस्य हैं जिनके पास ए के सदस्यों से अलग नाम हैं, और ए के सदस्यों के प्रकार हैं बी को सौंपा जा सकता है।

यह सब interface A extends B { ... } के व्यवहार के समान है, सिवाय इसके कि इसे टाइप फॉर्मूला द्वारा प्राप्त किया जाना चाहिए।

दूसरे शब्दों में, मुझे ऐसा कुछ चाहिए:

interface C extends B {
    [K in keyof A]: A[K];
    // this is invalid because members of interfaces must be statically determined in TS
}
// And I don't want an interface.

या इस तरह:

// About Omit:
// https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-5.html#the-omit-helper-type
type C = Omit<B, keyof A> & A;
// this can be invalid when B has
//     [k: string]: any;

मैं जानना चाहता हूं कि क्या मुझे निम्नलिखित रूप में टाइप सी मिल सकता है:

type A = { ... }
type B = { ... }
type C = A formula containing A and B
0
Y.Z. X. 20 जुलाई 2019, 18:10

1 उत्तर

सबसे बढ़िया उत्तर

आपका संस्करण type C = Omit<B, keyof A> & A; मेरे लिए एक अच्छा लगता है, इंडेक्स हस्ताक्षर की चेतावनी मैप किए गए प्रकारों के साथ एक सामान्य समस्या है।

आप यह समाधान। इसके साथ हम पहले ज्ञात कुंजियों को चुन सकते हैं, फिर किसी भी इंडेक्स string इंडेक्स सिग्नेचर और इंटरसेक्ट को A के साथ चुन सकते हैं:

type KnownKeys<T> = {
  [K in keyof T]: string extends K ? never : number extends K ? never : K
} extends { [_ in keyof T]: infer U } ? U : never;

type A = {
    a: number;
    b: string;
}

type B = {
    [a: string]: any;    
    d: number;
    b: string;
}

type C = Pick<B, Exclude<KnownKeys<B>, keyof A>> & Pick<B, string> & A;
declare let c: C;
c.d // d is still here
c[""] // index is still here

या अधिक सामान्य संस्करण:

type KnownKeys<T> = {
  [K in keyof T]: string extends K ? never : number extends K ? never : K
} extends { [_ in keyof T]: infer U } ? U : never;

type A = {
    a: number;
    b: number;
}

type B = {
    [a: string]: any;    
    d: number;
    b: string;
}

type Merge<T, U> = 
    // Picking the known keys from T, requires the introduction of K as a new type parameter
    // We do this in order to make TS know K is a keyof T on the branch we do the pick
    (Exclude<KnownKeys<T>, keyof U> extends infer K? K extends keyof T ? Pick<T, K> : never: never )
    // Pick the string index signature if any 
    & (T extends Record<string, any> ? Pick<T, string> : never) 
    // We can also pick the numeric index
    & (T extends Record<number, any> ? Pick<T, number> : never) 
    // Intersect with U 
    & U;
declare let c: Merge<B, A>;
c.d // d is still here
c[""] // index is still here`
3
Titian Cernicova-Dragomir 20 जुलाई 2019, 19:18