0

For a given object like:

class Product {
  constructor(
    public metadata: Metadata,
    public topic: Topic,
    public title = 'empty'
  ) {}
  ...
}

I want to create an interface:

interface State<T> {
}

such that TypeScript ensures that a product: State<Product> has the same structure as Product but its matching leaf-level properties are boolean. So product is supposed to have a title property of type boolean.


I had a look at the readonly example at mapped-types but in this case I probably need a composite:

interface State<T> {
  [p in keyof T]: typeof T[p] === 'object' ? State<T[p]> : boolean;
}

Any ideas of how to make this work?

2 Answers 2

3

You are close, your syntax is off, you need to use a type not an interface, and typeof T[p] === 'object' is written as T[p] extends object

class Metadata {
  constructor(
    public key = 'empty',
    public value = 'empty'
  ) { }
}
class Topic {
  constructor(
    public name = 'empty'
  ) { }
}
class Product {
  constructor(
    public metadata: Metadata[],
    public topic: Topic,
    public title = 'empty'
  ) { }

}

type State<T> = {
  [P in keyof T]: T[P] extends object ? State<T[P]> : boolean
}
let o: State<Product> = {
  title: true,
  topic: {
    name: true
  },
  metadata: [
    { key: true, value: false }
  ]
}

Playground link

Sign up to request clarification or add additional context in comments.

7 Comments

sounds promising, i'll have a look at it
for some reason compile breaks at extends keyword: TS1005: ';' expected.
@RobyRodriguez what version of TS are you using ? Code was tested on 3.4 in the playground, I will add a link
"typescript": "~2.7.2" :(
@RobyRodriguez yeah .. that will not work, you might get something working on 2.8 (arrays will be an issue, proper array handling in mapped types was added in 3.2 or 3.1 I belive) but 2.7 does not have conditional types
|
0

Use type instead of an interface:

type State<T> = { [P in keyof T]: boolean };

2 Comments

While not 100% clear, I think OP wants to map a nested structure with primitive properties being boolean
Oh, I have misunderstood then. "...but its matching leaf-level properties are boolean.", you're right. Well then he has your answer. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.