Skip to content

Force extra property checks if object is explicitly casted or at-least give us a StrictPropertyCheck/Exact type #32537

Closed

Description

@nojvek

TypeScript Version: 3.1.1

Search Terms: extra property checks, explicit cast, exact type

Code

interface Switch {
   on: boolean;
}
const a = <Switch>{on: false, blah: 123}; // no error, ¯\_(ツ)_/¯ 
const b: Switch = {on: false, blah: 123}; // error, may only specify known propery and blah is extra

Expected behavior:
Explicit cast should force extra property checks like the object literal does. I feel like TS team thinks this is intentional and may be a big breaking change.

Alternatively please give us an exact type if possible e.g StrictPropertyCheck<T> so we can do something like const b = <StrictPropertyCheck<SwitchState>>{...}

This stackoverflow thread has some magic vodoo for forcing extra property checks for functions that take arguments. https://stackoverflow.com/questions/54775790/forcing-excess-property-checking-on-variable-passed-to-typescript-function

type StrictPropertyCheck<T, TExpected, TError> = Exclude<keyof T, keyof TExpected> extends never ? {} : TError;

interface Animal {
    speciesName: string
    legCount: number,
}

function serializeBasicAnimalData<T extends Animal>(a: T & StrictPropertyCheck<T, Animal, "Only allowed properties of Animal">) {
    // something
}

Would be nice if we could have a similar mapped type that worked for objects.

Actual behavior:
No error

Playground Link:
https://typescript-play.js.org/#code/JYOwLgpgTgZghgYwgAgJIGED2BbADpkCcAHgGUw5IA+ZAbwChknmBnCyALmXMogG5GzJggIxgAcy4MhM5ABMI8AK4AbMD0gB+Lhv7IA9PrTIA7nHDzFcVevYowmZACMUbKMARgVAT2QIAFhAIANYQcshw4nCgbNx2yLhQmLjQYMAQLIKyTJB4KrzayAAUbLw6dgCUyAC8NObeArIAvlnMSrhyZcWlkACqHV0ACnBQaXAqZHZUVbXIAG6YwHICLfQI+SwsyFh4BERgk7w0wHkQ2PtbGDj4hCS6NNLMuEpOKh7IPRDlvAKtIiBuJSeTBQIpVR6yMD+YAsAB0nxqyAA8k4AFZBMCwuCbCQgIq0JoRLa6AA0yChMNh-zE4lhCmUal0FUazFWQmer3e4ggYD8ogkYLorSEUB5SigICF2Rk9OsjLsUkJ2LivBJwtZrTZbQGkBKdn6nU4yGGo2A40O1HB6qYKPRnixOPEeIpcM+ZM+Bt4zM19FW9FAkFgiBQpBMwDAAV0UuYBC4TkwmBUEHMK3oaw2xLDEf8Oxu+2QEAAHpAQHItrm9ncs5GptGmBy3ghkNzedSBVbpaKwOLJRDpZYGbYumRq-57rQDEYAOqYVThFzIEAeFDAGDk6FbEwg0LhLP+We8ou4RvhvzY3kOTDW-ux5DwFQsCBq-vZV5wfxcACMACYAMxkwxF0caAkigMkAHqAB0AH0ikAEYYKmg-RwKYABaSw4HCEQFGvIQmmfbIWjwtNfTTf5YjgRER3DGsjloW970fMk3w-ZAf1-Jo+EnICCygUCIJg+DEOQ5A1gIWInB0Uco2qOgGPGJjnHyVj2M47iQJBMlsDgXwCB8D4UgQVdfGCEBMBMSVEmSaBfHMedlOQGEC2LKA4CAA

Related Issues:
#9312, #28464

Activity

  1. changed the title [-]Force extra property checks if object is explicitly casted or at-least give us an exact type[/-] [+]Force extra property checks if object is explicitly casted or at-least give us a StrictPropertyCheck/Exact type[/+] on Jul 24, 2019
  2. RyanCavanaugh commented on Jul 24, 2019

    @RyanCavanaugh
    Member

    Sounds like #7481, though it's hard to tell because the example doesn't require a type assertion.

  3. nojvek commented on Jul 24, 2019

    @nojvek
    ContributorAuthor

    I'm not sure I understand #7481

    As per the typescript play example I would like someway of telling TS to give me stricter property checks that flow through form interface to concrete implementation.

    i.e

    interface IComponent<State> {
          state: State;
          config: {
              defaultState?: State; // some way to say I want this strict e.g StrictPropertyCheck<State>
              template?: (state: State) => any;
          }
          update: (stateUpdate: Partial<State>) => void;
    }
    
    class Component<State> implements IComponent<State> {
        public state: State;
    
        constructor() {
            this.state = Object.assign({} as State, this.config.defaultState);
        }
    
        public get config() {
            return {
                defaultState: {} as State,
            }
        }
    
        update(stateUpdate: Partial<State>) {
            Object.assign(this.state, stateUpdate);
        }
    }
    
    
    interface SwitchState {
        on: boolean;
    }
    
    class SwitchComponent extends Component<SwitchState> {
        public get config() {
            return {
                defaultState: {
                    on: false,
                    blah: 123, // no error, ¯\_(ツ)_/¯  - dead code - I want TS to throw error for extra properties
                },
            }
        }
    }
  4. RyanCavanaugh commented on Jul 24, 2019

    @RyanCavanaugh
    Member

    There's already a way to do that, though - put a return type annotation on config().

    #7481 covers the pros and cons of various options here

  5. nojvek commented on Jul 24, 2019

    @nojvek
    ContributorAuthor

    Oh cool, that worked. The question is why is the type not inferred from the base interface. Why do I have to tell TS again ?

    image

  6. typescript-bot commented on Jul 27, 2019

    @typescript-bot
    Contributor

    This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

  7. locked as resolved and limited conversation to collaborators on Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions