Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Property does not exist on selected type, but available via callback #60835

Open
edyth933 opened this issue Dec 21, 2024 · 3 comments
Open

Property does not exist on selected type, but available via callback #60835

edyth933 opened this issue Dec 21, 2024 · 3 comments

Comments

@edyth933
Copy link

edyth933 commented Dec 21, 2024

🔎 Search Terms

I was thinking this code works like how the addEventLister or on behavior happens. Are there other less complex solutions?

🕗 Version & Regression Information

  • This changed between versions ______ and _______
  • This changed in commit or PR _______
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
  • I was unable to test this on prior versions because _______

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/C4TwDgpgBAKgFhACgJwPZgM5QLxQN4BQUxUAZgJbIbABc+RJjAhsgOYAMd1y5AdqwG4GjYi1YBGLsB78hjAL7CoGCAGNUvACZ1CIkmM5ReAVwC2AIwjI5eqGIBMdc6lQAbCE143iixsDiU2vS2dmwAzFIygkrMbAAsdCYWVt5QiooEmmquLNDqvNRQ0iAAwuZ0ADwA0lAQAB7AEFpYANYQIKiksAgo6BgAfAAUYGhgAHJMphB0VQA0UKrlUMOjGHTwSKsA2lUAugCUOP1QAG6o5JqH2MdnFwQExWWDAOQq+ZrP8yN9RwsaGG4IAA6VyoVgrPpAhz7fb3fKFYoAMWMvFUOCg1VqDSamla7U63U2fSG33Gk2mUDmUFJa0JvUwOwOv10JHIXQhZKmOFwrzUGg+hxZenhgJBYI5GChbHssIUBEUQA

💻 Code

type TheProps = {
    first: {
        arg0: string;
        arg1: string;
    }
    second: {
        arg0: number;
        arg2: boolean;
    }
    third: {
        arg3: string;
        arg4: number;
    }
}

declare const tryCb: <K extends keyof TheProps>(propName: K, cb: (props: TheProps[K]) => void) => void

tryCb('second', props => console.log(props.arg2)) // => no error (although this should also be an error)

const tryFunc = <K extends keyof TheProps>(propName: K, props: TheProps[K]) => {
    if (propName == 'second') {
        console.log(props.arg2) // => error here
    }
}

🙁 Actual behavior

Property does not exist on selected type, but available via callback

🙂 Expected behavior

no error occurs same as using callback

Additional information about the issue

No response

@jcalz
Copy link
Contributor

jcalz commented Dec 21, 2024

This is not a bug in TS. The caller chooses the type argument (which is why you can do this when you call your function). The implementation needs to handle any choice the caller makes, including things like unions:

tryFunc(Math.random() < 0.999 ? 'second' : 'first', { arg0: "abc", arg1: "def" }); // no compiler error

Here there is a 99.9% chance you'll see "second" as the first argument, but the second argument has no arg2 property.

I think you need #27808 if you want to be able to narrow type parameters this way. The feature at #56941 for #33014 doesn't address this because TheProps[K] is in an input position.

@edyth933
Copy link
Author

so why don't tryCb and tryFunc make the same error or not?

@MartinJohns
Copy link
Contributor

With tryCb the compiler infers "second" for the type argument based on the provided parameters. This is not possible within tryFuc, because within the function you can't know what type is being passed in. That's what jcalz means with "the caller chooses the type argument".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants