const lines = ['one', 'two', 'three'] as const;
const linesWithA = lines.map(line => `${line}-A` as const);
const linesWithB = lines.map(line => `${line.toUpperCase()}-B` as const);
將給出型別:
declare const lines: readonly ["one", "two", "three"];
declare const linesWithA: ("one-A" | "two-A" | "three-A")[];
declare const linesWithB: `${string}-B`[];
是否有可能以某種方式獲得 linesWithB as 的型別("ONE-B" | "TWO-B" | "THREE-B")[]?我得到了?`${string}-A`[]相反,因為toUpperCase電話。
TS游樂場
uj5u.com熱心網友回復:
問題是toUpperCase剛剛回傳 a string:
const test1 = 'no uppercase'.toUpperCase();
// const test1: string
我認為處理這個問題最安全的方法是創建一個toUpperCase帶有斷言的新函式以獲得正確的型別:
const toUpperCase = <S extends string>(line: S) =>
line.toUpperCase() as Uppercase<S>
const test2 = toUpperCase('uppercase');
// const test2: "UPPERCASE"
如果在 中使用此函式linesWithB,它將具有所需的回傳型別:
const linesWithB = lines.map(line => `${toUpperCase(line)}-B` as const);
// const linesWithB: ("ONE-B" | "TWO-B" | "THREE-B")[]
游樂場鏈接
更新:有一個關于這個的TypeScript 問題,但它(可能?)需要String通用,這是一個相當廣泛的變化。
uj5u.com熱心網友回復:
I can only do it with a (fairly innocuous) type assertion:
const lines = ['one', 'two', 'three'] as const;
type Lines = typeof lines;
type UpperLines = Uppercase<Lines[number]>[];
const linesWithA = lines.map(line => `${line}-A` as const);
const linesWithB = (lines.map(line => line.toUpperCase()) as UpperLines).map(line => `${line}-B` as const);
Playground link
It's also possible without the intermediary type aliases, but...I wouldn't:
const lines = ['one', 'two', 'three'] as const;
const linesWithA = lines.map(line => `${line}-A` as const);
const linesWithB = (lines.map(line => line.toUpperCase()) as [Uppercase<(typeof lines)[number]>]).map(line => `${line}-B` as const);
Playground link
Hopefully someone better at TypeScript than I can do it without the type assertion, though again, it's fairly innocuous.
uj5u.com熱心網友回復:
You could augment the global namespace and add an overload for the toUpperCase function:
declare global {
interface String {
toUpperCase<T extends string>(this: T): Uppercase<T>
}
}
No type assertion is required:
// ("ONE-B" | "TWO-B" | "THREE-B")[]
const linesWithB = lines.map(line => `${line.toUpperCase()}-B` as const)
Playground link
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/451847.html
標籤:打字稿
