Timer with interval function
First of all, your function doesn't return anything and so you can remove -&gt; bool since it only creates confusion. You can either use -&gt; None or use nothing at all. Still related to type annotations, I find it kinda hard to read your code with annotations everywhere. This is subjective and it's just my personal preference but I usually tend to use type annotations only when dealing with function / class definitions and their arguments.
For example, milliseconds: int = int(round(time.time() * 1000)) it's obviously going to be an integer since we can see the cast to int().
More, round() already returns an int in your case so that can be removed as well. The done variable can also be omitted and added directly to the condition itself:
def set_timer(interval: int, function: Callable) -&gt; None:
    global last_milliseconds
    milliseconds = round(time.time() * 1000)
    
    if milliseconds - last_milliseconds &gt;= interval:
        function()
        last_milliseconds = milliseconds

You can also remove the parentheses from your condition since - has a higher precedence than &gt;=.

Strictly speaking about the implementation, if you're not tied to using a function and want to get rid of the usage of global, I'd use a class:
from time import time
from typing import Callable


class Timer:
    def __init__(self):
        self.last_milliseconds = 0

    def set(self, interval: int, function: Callable) -&gt; None:
        milliseconds = round(time() * 1000)

        if milliseconds - self.last_milliseconds &gt;= interval:
            function()
            self.last_milliseconds = milliseconds

Which can be used like this:
def main():
    timer = Timer()
    while True:
        timer.set(1000, lambda: print(&quot;set_timer called.&quot;))


main()

Or, even better, you can have a static class if your workflow allows it:
class StaticTimer:
    last_milliseconds = 0

    @classmethod
    def set(cls, interval: int, function: Callable) -&gt; None:
        milliseconds = round(time() * 1000)

        if milliseconds - cls.last_milliseconds &gt;= interval:
            function()
            cls.last_milliseconds = milliseconds

Which you'd call like this:
def main():
    while True:
        StaticTimer.set(1000, lambda: print(&quot;set_timer called.&quot;))


main()

The difference between the two classes is that you can't have multiple of the latter because of the class attribute and @classmethod. So even if you made multiple instance of the class, they'd all share that value.