destructuring - Destrukturera alla egenskaper av en kombinerad typ i Typescript


Finns det ett enkelt sätt, eller syntaktiskt socker, för att dela upp en kombinerad typ tillbaka till en basklass utan att ange alla egenskaper för hand.

type AType = {
  A1Prop: string
  A2Prop: string
  SharedProp: string
}

type BType = {
  B1Prop: string
  B2Prop: string
  SharedProp: string
}

type ABType = AType & BType

const someObject: ABType = {
  A1Prop: 'string',
  A2Prop: 'string',
  B1Prop: 'string',
  B2Prop: 'string',
  SharedProp: 'string'
} 

// destructure here all props of AType
const { A1Prop, A2Prop, SharedProp, ...rest } = someObject
// and split it manually 
const AllPropsOfA : AType = {A1Prop, A2Prop, SharedProp} 
const AllPropsOfB : BType = {...rest, SharedProp}

Finns det ett enklare sätt utan att specificera alla egenskaper av Atype.
Kanske finns det en hjälpfunktion tillgänglig? på linje med: const AllPropsOfA=GetAllPropsOf<AType>(someObject)

det resulterande objektet ska endast innehålla egenskaper av AType,

{
  "A1Prop": "string",
  "A2Prop": "string",
  "SharedProp": "string"
}

Svar #1

Du kan använda nyckelordet as:

const aType = someObject as AType;
const bType = someObject as BType;

Svar #2

Om du bara letar efter en lösning på typnivå, är someObject helt tilldelningsbar till både AType och BType variabler utan några problem:

type AType = {
  A1Prop: string
  A2Prop: string
  SharedProp: string
}

type BType = {
  B1Prop: string
  B2Prop: string
  SharedProp: string
}

type ABType = AType & BType

const someObject: ABType = {
  A1Prop: 'string',
  A2Prop: 'string',
  B1Prop: 'string',
  B2Prop: 'string',
  SharedProp: 'string'
} 

const AllPropsOfA : AType = someObject // ok
const AllPropsOfB : BType = someObject // ok

lekplatslänk

Typer är slags öppna i TypeScript och om du inte aktiverar kontroll av överflödiga egenskaper är det okej att tilldela en mer konkret typ till en mer generell.


Men om din fråga handlar om manipulationer vid körningstid blir saker och ting lite mer komplicerade. Typer existerar inte vid körningstid och du blir kvar endast med någon form av knep och lösningar.

const ATypeProps = ['A1Prop', 'A2Prop', 'SharedProp'] as const
const BTypeProps = ['B1Prop', 'B2Prop', 'SharedProp'] as const

type ATypeKeys = typeof ATypeProps[number]
type BTypeKeys = typeof BTypeProps[number]

type AType = { [K in ATypeKeys]: string }
type BType = { [K in BTypeKeys]: string }


const someObject = {
  A1Prop: 'string',
  A2Prop: 'string',
  B1Prop: 'string',
  B2Prop: 'string',
  SharedProp: 'string'
}

const pick = <T, K extends keyof T>(obj: T, keys: readonly K[]): Pick<T, K> => {
  const result = {} as Pick<T, K>
  keys.forEach((key) => result[key] = obj[key])
  return result
}

const AllPropsOfA: AType = pick(someObject, ATypeProps)
/* {
  "A1Prop": "string",
  "A2Prop": "string",
  "SharedProp": "string"
} */


const AllPropsOfB: BType = pick(someObject, BTypeProps)
/* {
  "B1Prop": "string",
  "B2Prop": "string",
  "SharedProp": "string"
} */

lekplatslänk