11

In typescript we have Partial type, so we can do this:

interface Foo {
    x:number
    y:number
}

const foo:Partial<Foo> = {x: 1}

(With this we can make all properties of an interface optional)

In Python, we could do this with a total=False, like this:

from typing_extensions import TypedDict


class Foo(TypedDict, total=False):
    x:int
    y:int

foo:Foo = {'x':1}

But this approach is not too good, because this implies that all Foo must have all properties as possible None, and we need to do a lot of typecasting. Is there, in python, a way to declare a TypedDict and then make some implementation of it a subset of this type, like this:

from typing_extensions import TypedDict


class Foo(TypedDict):
    x: int
    y: int


foo:Partial[Foo] = {'x': 1}
Michael M.
  • 10,486
  • 9
  • 18
  • 34
vacih86456
  • 237
  • 1
  • 7
  • 1
    For those of us not intimately familiar with TypeScript, can you clarify what behaviour you expect? The linked docs say that is ``Partial`` is a type with "all properties of ``Type`` set to optional". That seems to match "that all ``Foo`` must have all properties as possible None". Do you want to have *two* versions of ``Foo``, one with all properties non-optional and one with all properties optional? – MisterMiyagi Sep 07 '21 at 17:12
  • 3
    I wrote a commend about Partial in my last Edit. But the idea is that typescript `Partial` allows us to take an interface whose properties is all required and turn all those properties into optional so that we can make implementations of this interface a subset of it but keep the interface property's required. `total=True` doesn't allow that, because we need to change the `TypedDict` directly. – vacih86456 Sep 07 '21 at 17:35
  • 2
    I think the answer is that this probably isn't really possible in python currently. But, you could always write a PEP for it, if you feel it's something the language is currently lacking. – Alex Waygood Sep 07 '21 at 19:44
  • 1
    Why not defining a second type `PartialType` which is just equal to `Partial`? – coccoinomane May 23 '22 at 18:50
  • 2
    Part of the problem here is that the static type is supposed to prescribe what value can be assigned to `foo`, rather than the type inferring the desired structure *from* an arbitrary value. Python's type system is, I think, too different from the one used by TypeScript to support such an operation. – chepner Sep 30 '22 at 19:27
  • 2
    Instead of trying to fit the mold exactly from the structure in Typescript, could you instead post the relevant Python code which is awkward to write because of this issue? I think you might be able to use a different pattern to alleviate the issues you find due to the lack of this pattern. Otherwise this feels more like an x y problem. – flakes Oct 03 '22 at 03:56
  • I have a generic class with a `TypedDict` type argument, and I'm essentially implementing a `dict.update`, which allows for changing only parts of the `TypedDict`. Without some kind of `Partial` type decorator, every call to the `dict.update` analog is marked incorrect unless its dict arg defines _all_ the `TypedDict` fields — which is semantically incorrect, as defining those fields changes the functionality (and can result in race conditions, when the underlying dict has changed in between access and update). – theY4Kman Dec 21 '22 at 19:34

1 Answers1

3

From Python3.11, we have typing.NotRequired. The Doc is Here, and PEP is Here.

This marks variable as potentially-missing.

Like

from typing import TypedDict, NotRequired

class Movie(TypedDict):
    title: str
    year: NotRequired[int]
nagataaaas
  • 400
  • 2
  • 13
  • 1
    While this goes in the right direction, to have the equivalent to TS, we would need something like `Partial[Movie]` to return a version of movie where every property is `NotRequired`. – Kao Félix Aug 02 '23 at 14:25