TS2339 - 'Property doesn't exist on type' error in an apparently valid TS file

后端 未结 2 1870
孤独总比滥情好
孤独总比滥情好 2020-12-21 07:48

I have the following type declarations:

type Root = { r: string };
type A = { a: string };
type B = { b: string };
type Main = Root & (A | B);

相关标签:
2条回答
  • 2020-12-21 08:24

    There's the problem that the compiler can't make sure that either .a or .b are available at this point, because that's going to be validated within runtime. As soon as you create a variable of type Main, you'll specify what specialized type of Main it is. So either Root & A or Root & B.

    To make sure that .a or .b are accessible within that function just do the following:

    type Root = { r: string };
    type AB = { a?: string, b?: string };
    type Main = Root & AB;
    
    const func = (main: Main): void => {
        if ('a' in main) {
            main.a!
        } else {
            main.b!
        }
    }
    
    0 讨论(0)
  • 2020-12-21 08:30

    You are right about Main being equivalent to (Root & A) | (Root & B) you are wrong about the interpretation of union types (|). A union type means you can assign either type in the union to main ( so either (Root & A) or (Root & B)), but you can only access common properties of the union members. In this case the common member is only r. Since main ca be either (Root & A) or (Root & B), a might not exist on main, so typescript prevents such an access.

    To use the members that only exist on one type in the union you need a type guard. In this case an in type-guard will work best:

    const func : (main: Main) => void = main => {
        if ('a' in main) {
            main.a
        } else {
            main.b
        }
    }
    

    You can read more about type guards here

    0 讨论(0)
提交回复
热议问题