Хорошо:
const [foo, setFoo] = useState<string>()
Это не:
const [boo, setBoo] = useState<string>(undefined)
Аргумент типа «неопределенный» не может быть присвоен параметру типа «строка | (() => строка)'
Я думаю, что они имеют то же значение, хотя - useState без аргументов то же самое, что и useState(undefined).
Просто TypeScript по какой-то причине не может это обнаружить?
const [foo, setFoo] = useState<string>(" ");





Потому что определение DefinitelyTyped перегружено 2 сигнатурами для useState, одна из которых не имеет аргументов:
// with argument
function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];
// no argument
function useState<S = undefined>(): [S | undefined, Dispatch<SetStateAction<S | undefined>>];
Если вы хотите, чтобы определение аргумента допускало undefined, вам нужно явно определить его следующим образом:
const [boo, setBoo] = useState<string|undefined>(undefined)
useState<string>() — это условное сокращение для useState<string|undefined>(undefined)
Типография здесь
function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];
// convenience overload when first argument is omitted
// ...
function useState<S = undefined>(): [S | undefined, Dispatch<SetStateAction<S | undefined>>];
Как указано в комментарии к коду, это просто удобство, а не упущение, а намеренно.
Не используйте это, ваше состояние должно строго быть string, так как отсутствие аргумента делает undefined также разрешенным.
Побочный момент: это также позволяет useState() без аргумента или аргумента типа, что приводит к объекту состояния, который может быть только undefined
Поскольку формы без аргументов и формы с одним аргументом различаются, их начальное значение undefined не имеет значения: github.com/DefinitelyTyped/DefinitelyTyped/blob/…