我試圖讓一個函式回傳兩種可能的資料型別。它可以回傳的第一種型別是它可以回傳string的第二種型別fs.WriteStream
在函式中,這基于您傳遞給它的引數,稱為 stream?: boolean
正如你在圖片中看到的,VSCode 正確地顯示了這個函式的這種行為


但是,不知何故,智能感知僅將其識別為一段string時間,實際型別也可能是fs.WriteStream

但是如果我強迫它fs.WriteSteam使用
const tt = await getFromUrl(s, true) as fs.WriteStream;
它作業正常

這是怎么回事?如何在不強制它為type 的情況下使此 union 型別正常作業?
這是您不想復制的完整代碼
import { existsSync, readFileSync } from 'fs'
import https from 'https'
import fs from 'fs'
import crypto from 'crypto'
/**
* Converts given source from a SRT format to a WebVTT format
*
* Srt must be one of type
* - Path to subtitle file (only for NodeJS environments)
* - URL to a subtitle file (for browser and NodeJS)
* - SRT text content (for browser and NodeJS)
*
* @param srt { string }
* @returns string
* @example
* convert(`./path/to/subtitle.srt`) // only for nodejs
* convert(`https://example.com/english.srt`) // works for both browser and nodejs
* convert(`1
00:00:00,207 --> 00:00:05,520
Amerikaanse Ministerie
van Magie.
2
00:00:06,625 --> 00:00:09,034
New York, 1927
3
00:00:10,878 --> 00:00:15,547
Je zal blij zijn van hem af te zijn
neem ik aan?`) // works for both browser and nodejs
*/
export async function convert(srt: string) {
const s = srt.trim()
const isUri = s.startsWith("http://") || s.startsWith("https://")
const isPath = /^([a-z]:)?([.\/] )?((\\|\/|\\\\)?[a-z0-9\s_@\-^!#$%& ={}\[\]] ) \.srt$/i.test(s)
if(isPath && existsSync(s)) {
return srtToVtt(readFileSync(s, 'utf8'));
}
if(isUri) {
const tt = await getFromUrl(s);
console.log(tt.path);
}
// Must be the contents of an srt file of we get here
return ''
}
/**
* Fetches text content from srt file over web
*
* @param url
* @param stream - return result as a writeable stream or just the data (default true)
*/
export async function getFromUrl(srt: string, stream = true): Promise<string | fs.WriteStream> {
return new Promise(resolve => {
https.get(srt, response => {
if(stream) {
const str = fs.createWriteStream(crypto.randomBytes(16).toString("hex") '.srt')
response.pipe(str).on('finish', () => {
str.end().close();
return resolve(str)
})
} else {
let srtFile = '';
response.on("data", function(chunk) {
srtFile = chunk;
});
response.on('end', () => {
console.log('test')
return resolve(srtFile)
})
}
})
})
}
uj5u.com熱心網友回復:
為什么會出現此錯誤:
tt變數的型別是string | fs.WriteStream。由于您不知道該變數中有兩種型別中的哪一種,因此您想要訪問的任何方法或屬性都必須存在于這兩種型別中。
如您所見,您可以通過將變數的型別縮小到該聯合的一側或另一側來解決此問題。您可以使用手動轉換(您的as fs.WriteStream)來做到這一點,或者如果您使用控制流檢查,TypeScript 可以推斷出正確的型別:
if (typeof tt === "string") {
// tt has type string in this block.
return;
}
// tt has type fs.WriteStream from here forward.
考慮一個多載:
此功能可能會受益于多載簽名,因此您獲得的聯合部分的歧義被消除。這樣,TypeScript 可以根據您呼叫函式的方式推斷出正確的回傳型別。
async function getFromUrl(srt: string, stream?: false): Promise<string>;
async function getFromUrl(srt: string, stream: true): Promise<fs.WriteStream>;
async function getFromUrl(srt: string, stream?: boolean): Promise<string | fs.WriteStream> {
return ""
}
const str1 = await getFromUrl("") // string
const str2 = await getFromUrl("", false) // string
const stream = await getFromUrl("", true) // fs.WriteStream
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/409688.html
標籤:
上一篇:基于prop的動態方法簽名?
下一篇:匯出時未應用可空型別
