2

I have following function:

function doSomething(param1: string, param2: string) {
  return param1 + param2;
}

also I have json based type with structure looking similar to this:

a1: {
  b1: 'something1',
  b2: 'something2',
  b3: 'something3'
},
a2: {
  c1: 'something4',
  c2: 'something5'
}

...etc

I want nth argument of mentioned function to be literal of nth deep elements, so if first argument is 'a1', second should be 'b1' | 'b2' | 'b3', and if first argument is 'a2', second should be 'c1' | 'c2'.

For first argument I've made simple keyof typeof data type, which is working great:

// data is imported json
type FirstArg = keyof typeof data;

For second I was trying generic type like this, but without success:

type SecondArg<T extends FirstArg> = keyof typeof data[T];

Any chance to do that?

1 Answer 1

3

You can't do it for any number of arguments, you can define overloads for up to a specific depth:

const data = {
    a1: {
        b1: 'something1',
        b2: 'something2',
        b3: 'something3'
    },
    a2: {
        c1: 'something4',
        c2: 'something5'
    }
}
type DataType = typeof data;
function doSomething<K extends keyof DataType, K2 extends keyof DataType[K]>(p1: K, p2: K2, p3: keyof DataType[K][K2]): string
function doSomething<K extends keyof DataType>(p1: K, p2: keyof DataType[K]): string
function doSomething(p1: keyof DataType): string
function doSomething(...keys: PropertyKey[]) {
    return keys.join('.');
}

doSomething("a1", "b1")
doSomething("a1", "c2") // err
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that's sufficient solution for my problem.

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.