#typescript #typescript-typings #typescript-generics
#typescript #typescript-typings #typescript-generics
Вопрос:
У меня есть функция, которая принимает строку или массив строк и возвращает объект с ключами этой строки.
Вот фиктивная функция:
type myType<T extends string> = { [K in T]: string }
const myFunc = <T extends string>(param: T | T[]): myType<T> => {
let result = <myType<T>>{}
// some codes here...
return resu<
}
С помощью приведенного выше кода я уже добился этого:
let val = myFunc(['foo', 'bar']);
val.foo // valid
val.other // invalid
Но если я передам переменную в функцию, все строковые ключи будут действительными:
let variable = ['foo', 'bar'];
let val = myFunc(variable);
val.foo // valid
val.other // valid
Есть ли обходной путь, чтобы я мог передать переменную, но все еще работал так, как я ожидал?
Комментарии:
1. Я думаю, вам нужно что-то вроде
string extends T ? never :
, но я не знаю, какой синтаксис для этого
Ответ №1:
Когда вы создаете переменную let variable = ['foo', 'bar']
, тип variable
становится string[]
, и вы теряете информацию о конкретных строках в массиве. Вам нужно использовать as const
, чтобы Typescript интерпретировал variable
как фиксированный кортеж строковых литералов 'foo'
и 'bar'
. Поскольку этот фиксированный кортеж является readonly
, вам также необходимо изменить свою функцию, чтобы принимать readonly
массивы.
const myFunc = <T extends string>(param: T | readonly T[]): myType<T> => {
let variable = ['foo', 'bar'] as const;
let val2 = myFunc(variable);
val2.foo // valid
val2.other // invalid
Комментарии:
1. Есть ли способ не использовать
as const
? Его легко забыть добавить, и ошибка не выдается.2. Ну, вы можете передать ее непосредственно в функцию, но вы уже сказали, что не хотите этого делать. Вы можете назначить явный тип
let variable: ['foo', 'bar'] = ['foo', 'bar']
.